home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / ms_dos / nifp / nifpsub.c < prev    next >
C/C++ Source or Header  |  1993-07-08  |  76KB  |  3,433 lines

  1. /*
  2.  *     このモジュールは,NIFPのサブルーチン部です。主にファイル処理と画面表示とキー入力を
  3.  *    処理します。
  4.  *     このモジュールは,マシン依存しています。
  5.  *
  6.  *    このモジュール中でPC88VAに関するソースは Nifty-Serve ID:NBB00541 てんか☆(北
  7.  *    村)が作成しました。
  8.  */
  9.  
  10. #include "nifp.h"
  11. #include <signal.h>
  12.  
  13. char savepflag=0,erron=0;
  14. #ifdef FMR
  15. #define RTN_CODE 0x1f
  16. #define TAB_CODE 0x1c
  17. #define KEYMAX 24
  18. static char pfkeyset[2];
  19. char keygettbl[KEYMAX][16];
  20. char keysettbl[KEYMAX*2] = { 0x01,'1',0x02,'2',0x03,'3',0x04,'4',0x05,'5',
  21.                               0x06,'6',0x07,'7',0x08,'8',0x09,'9',0x0a,':',
  22.                              0x0b,';',0x1d,'<',0x21,'=',0x22,'>',0x23,'?',
  23.                              0x24,'@',0x25,'A',0x26,'B',0x27,'C',0x28,'D',
  24.                              0x16,'E',0x17,'F' };
  25. #define KEY2MAX 11
  26. char keyget2tbl[KEY2MAX][10];
  27. char keyset2tbl[KEY2MAX*3] = { 0x08,0x08,0x09,0x09,0x0b,0x0b,0x0c,0x0c,
  28.                                0x0d,0x0d,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,
  29.                                0x1e,0x1e,0x1f,0x1f,0x7f,0x00 };
  30. unsigned int pftbl[4];
  31. char pfdata[70],pfsdata[70],pfcdata[70],pfscdata[70],pfadata[70];
  32. struct ATR {
  33.     char    moji,atr;
  34.     unsigned int color;
  35. } pfatr[70],pfsatr[70],pfcatr[70],pfscatr[70],pfaatr[70];
  36. int atr1=0x07;
  37. static char machineinfo[16];
  38. static char dispmode=0;
  39. #endif
  40. #ifdef PC_98
  41. #define RTN_CODE 0x1f
  42. #define TAB_CODE 0x1c
  43. char pfdata[250],pfsdata[250],pfcdata[250],pfscdata[250],pfadata[250];
  44. char atr=0xe1;
  45. long vramadr = 0xa000;
  46. long vramatr = 0xa200;
  47. #endif
  48. #ifdef PC_AT
  49. #define RTN_CODE 0x1b
  50. #define RTNAX_CODE 0x05
  51. #define TAB_CODE 0x1e
  52. #define AT 0
  53. #define AX 1
  54. #define DOSV 2
  55. #define J3100 3
  56. int at_keta = 80;
  57. int at_line = 25;
  58. char actpage = 8;
  59. char pfdata[300],pfsdata[300],pfcdata[300],pfscdata[300],pfadata[300];
  60. char atr=0x07;
  61. long vramadr = 0xb800;
  62. static char dispmode=AT;
  63. static int cslmode = 0;
  64. static char sclmode = 0;
  65. #endif
  66. int saveshift=0;
  67. time_t lsavetime[1];
  68.  
  69.  
  70. #ifdef PC88VA
  71. /* VA : MSE の モード */
  72. #define VA_PC9801  -2    /* not VA */
  73. #define VA_NOMSE   -1
  74. #define VA_NATIVE  0
  75. #define VA_STD     1
  76. #define VA_TEXT98  2
  77. #define VA_TEXT98K 3
  78. #define VA_MONO98  4
  79. #define VA_GRPH98  5
  80.  
  81. static char dflt_atr = 0xE1;
  82. static int  saveMseMode = VA_PC9801;
  83. #endif
  84.  
  85. static int xint86(char i)
  86. {
  87.     return(int86(i,®s,®s));
  88. }
  89.  
  90. static int xint86x(char i)
  91. {
  92.     return(int86x(i,®s,®s,&sregs));
  93. }
  94.  
  95. static int xint90(void)
  96. {
  97.     return(xint86(0x90));
  98. }
  99.  
  100. static int xint91(void)
  101. {
  102.     return(xint86(0x91));
  103. }
  104.  
  105. static int xint90x(void)
  106. {
  107.     return(xint86x(0x90));
  108. }
  109.  
  110. static int xint91x(void)
  111. {
  112.     return(xint86x(0x91));
  113. }
  114.  
  115. static int xintdos(void)
  116. {
  117.     return(intdos(®s,®s));
  118. }
  119.  
  120. #ifdef PC88VA
  121. static int Va_ChkVA(void)
  122. {
  123.     return (*((unsigned char far *)0xffff000fL) == 0xff);
  124. }
  125.  
  126. static int Va_GetMseMode(void)
  127. {
  128. /*    if (Va_ChkVA() == 0)
  129.         return(VA_PC9801); */
  130.     regs.x.cx = -1;
  131.     regs.x.ax = 0x44e5;
  132.     regs.h.dl = 0xff;
  133.     xintdos();
  134.     if ((int)(regs.x.cx) != -1) {
  135.         return ((regs.h.dh < 0x40) ? VA_STD :
  136.                ((regs.h.dh < 0x80) ? ((regs.h.dh&0x10) ? VA_TEXT98K:VA_TEXT98):
  137.                ((regs.h.dh == 0x80) ? VA_MONO98: VA_GRPH98)));
  138.     }
  139.     regs.x.ax = 0x7f00;
  140.     xintdos();
  141.     regs.x.cx = -1;
  142.     regs.x.ax = 0x44e5;
  143.     regs.h.dl = 0xff;
  144.     xintdos();
  145.     if ((int)(regs.x.cx) == -1)
  146.         return(VA_NOMSE);
  147.     regs.x.ax = 0x7f01;
  148.     xintdos();
  149.     return(VA_NATIVE);
  150. }
  151.  
  152. static int Va_SetMseMode(int mode)
  153. {
  154.     if (mode == VA_NATIVE) {
  155.         regs.x.ax = 0x7f01;
  156.         xintdos();
  157.         return(0);
  158.     }
  159.     regs.x.ax = 0x7f00;
  160.     xintdos();
  161.     regs.x.cx = 0;
  162.     regs.x.ax = 0x44e5;
  163.     regs.h.dl = 0x00;
  164.     regs.h.dh = ((mode == VA_STD) ? 0x00 :
  165.                 ((mode == VA_TEXT98) ? 0x45 :
  166.                 ((mode == VA_TEXT98K)? 0x45|0x10 :
  167.                 ((mode == VA_MONO98) ? 0x80 :
  168.                 ((mode == VA_GRPH98) ? 0x85 : 0xFF)))));
  169.     if (regs.h.dh == 0xFF)
  170.         return(-1);
  171.     xintdos();
  172.     return(0);
  173. }
  174.  
  175. static void Va_FuncKeySw(int n)
  176.     /* n = 0: モジレツ テンカイ スル   1:シナイ */
  177. {
  178.     regs.x.ax = 0x0200+(n & 0x01);
  179.     xint86(0x82);
  180. }
  181. #endif
  182.  
  183. #ifdef FMR
  184. static unsigned xjmstojis(unsigned c)
  185. {
  186.     int h,l;
  187.  
  188.     h = c/256;
  189.     l = c%256;
  190.     h -= (h <= 0x9f) ? 0x71 : 0xb1;
  191.     h = h * 2 + 1;
  192.     if(l > 0x7f) l--;
  193.     if(l >= 0x9e) {
  194.         l -= 0x7d;
  195.         h++;
  196.     }
  197.     else l -= 0x1f;
  198.     return(h*256+l);
  199. }
  200. #endif
  201.  
  202. void loc(int x,int y)        /* カーソル位置設定 */
  203. {
  204.     gyo = y;
  205.     keta = x;
  206. #ifdef FMR
  207.     if(dispmode)
  208.         vramoffset = ((y-1)*160 + (x-1)*2);
  209.     else {
  210.         regs.h.ah = 0x0d;
  211.         regs.h.dh = y;
  212.         regs.h.dl = x;
  213.         xint91();
  214.     }
  215. #endif
  216. #ifdef PC_98
  217.     vramoffset = ((y-1)*160 + (x-1)*2);
  218. #endif
  219. #ifdef PC_AT
  220.     if(dispmode)
  221.         vramoffset = ((y-1)*at_keta*2 + (x-1)*2);
  222.     else {
  223.         regs.h.ah = 0x02;
  224.         regs.h.bh = actpage;
  225.         regs.h.dh = y-1;
  226.         regs.h.dl = x-1;
  227.         xint86(0x10);
  228.     }
  229. #endif
  230. }
  231.  
  232. void locate(int x,int y)    /* カーソル位置設定 */
  233. {
  234.     loc(x,y);
  235. #ifndef PC_AT
  236.     printf("\033[%d;%dH",y,x);
  237. #else
  238.     regs.h.ah = 0x02;
  239.     regs.h.bh = actpage;
  240.     regs.h.dh = y-1;
  241.     regs.h.dl = x-1;
  242.     xint86(0x10);
  243. #endif
  244. }
  245.  
  246. void xlocate2(void)            /* カーソル最終行位置設定 */
  247. {
  248.     locate(1,line-1);
  249. }
  250.  
  251. void xlocate(void)            /* カーソル最終行位置設定 & 行クリア */
  252. {
  253.     xlocate2();deforutoiro();clr();
  254. }
  255.  
  256. #ifdef PC_AT
  257. static void dosv_disp(long off,int c)    /* 画面表示の更新 */
  258. {
  259.     regs.h.ah = 0xff;        /* 疑似ビデオ・バッファをグラフィックVRAM に転送 */
  260.     sregs.es = (unsigned)vramadr;
  261.     regs.x.di = (unsigned)off;
  262.     regs.x.cx = (unsigned)c;
  263.     xint86x(0x10);
  264. }
  265. #endif
  266.  
  267. void scroll(int mode,int x1,int y1,int x2,int y2) /* スクロール */
  268. {
  269. #ifdef FMR
  270.     regs.h.ah = 0x1a;
  271.     regs.h.al = mode;
  272.     regs.x.cx = 1;
  273.     regs.h.dh = y1;
  274.     regs.h.dl = x1;
  275.     regs.h.bh = y2;
  276.     regs.h.bl = x2;
  277.     xint91();
  278. #endif
  279. #ifdef PC_98
  280.     int y,x;
  281.     int far *ap;
  282.     int far *atp;
  283.     int far *bp;
  284.     int far *btp;
  285.  
  286.     if(mode) {
  287.         ap = (int far *)(MK_FP(vramadr,(y2-2)*160));
  288.         atp = (int far *)(MK_FP(vramatr,(y2-2)*160));
  289.         for(y = y2-1; y >= y1; y--) {
  290.             bp = ap + 80;
  291.             btp = atp + 80;
  292.             for(x = x1-1; x < x2;x++) {
  293.                 *(bp+x) = *(ap+x);
  294.                 *(btp+x) = *(atp+x);
  295.             }
  296.             ap -= 80;
  297.             atp -= 80;
  298.         }
  299.         ap = (int far *)(MK_FP(vramadr,(y1-1)*160));
  300.         atp = (int far *)(MK_FP(vramatr,(y1-1)*160));
  301.         for(x = x1-1; x < x2;x++) {
  302.             *(ap+x) = 0;
  303.           #ifdef PC88VA
  304.             *(atp+x) = dflt_atr;
  305.           #else
  306.             *(atp+x) = 0x00e1;
  307.           #endif
  308.         }
  309.     }
  310.     else {
  311.         ap = (int far *)(MK_FP(vramadr,(y1-1)*160));
  312.         atp = (int far *)(MK_FP(vramatr,(y1-1)*160));
  313.         for(y = y1-1; y < y2-1; y++) {
  314.             bp = ap + 80;
  315.             btp = atp + 80;
  316.             for(x = x1-1; x < x2;x++) {
  317.                 *(ap+x) = *(bp+x);
  318.                 *(atp+x) = *(btp+x);
  319.             }
  320.             ap += 80;
  321.             atp += 80;
  322.         }
  323.         ap = (int far *)(MK_FP(vramadr,(y2-1)*160));
  324.         atp = (int far *)(MK_FP(vramatr,(y2-1)*160));
  325.         for(x = x1-1; x < x2;x++) {
  326.             *(ap+x) = 0;
  327.           #ifdef PC88VA
  328.             *(atp+x) = dflt_atr;
  329.           #else
  330.             *(atp+x) = 0x00e1;
  331.           #endif
  332.         }
  333.     }
  334. #endif
  335. #ifdef PC_AT
  336.     int y,x;
  337.  
  338.     if(mode) {                /* スクロールダウン */
  339.         regs.x.ax = 0x0701;
  340.         regs.h.bh = 0;
  341.         regs.h.ch = y1-1;
  342.         regs.h.cl = x1-1;
  343.         regs.h.dh = y2-1;
  344.         regs.h.dl = x2-1;
  345.         xint86(0x10);
  346.     }
  347.     else {                    /* スクロールアップ */
  348.         regs.x.ax = 0x0601;
  349.         regs.h.bh = 0;
  350.         regs.h.ch = y1-1;
  351.         regs.h.cl = x1-1;
  352.         regs.h.dh = y2-1;
  353.         regs.h.dl = x2-1;
  354.         xint86(0x10);
  355.     }
  356. #endif
  357. }
  358.  
  359. int getline(void)        /* 画面行数読み取り */
  360. {
  361. #ifdef FMR
  362.     regs.h.ah = 0x04;
  363.     xint91();
  364.     return((int)regs.h.dh);
  365. #endif
  366. #ifdef PC_98
  367.   #ifdef PC88VA
  368.     if (vrammode == 3) {
  369.         regs.h.ah = 0x0b;
  370.         xint86(0x18);
  371.         if(regs.h.al & 0x01)
  372.             return(20);
  373.         return(25);
  374.       } else {
  375.   #endif
  376.     unsigned char far *nec_line = (unsigned char far *)0x000712L;
  377.     int c;
  378.  
  379.     c = (int)*nec_line;
  380.     if(!vrammode) {
  381.         if(c > 25) c++;
  382.     }
  383.     return(c+1);
  384.   #ifdef PC88VA
  385.     }
  386.   #endif
  387. #endif
  388. #ifdef PC_AT
  389.     unsigned char far *ibm_keta = (unsigned char far *)0x40004aL;
  390.     unsigned char far *ibm_line = (unsigned char far *)0x400084L;
  391.  
  392.     at_keta = (int)*ibm_keta;
  393.     at_line = (int)*ibm_line + 1;
  394.     return(at_line);
  395. #endif
  396. }
  397.  
  398. static char ctlcsave=0;
  399. static void (*savesignal)();
  400.  
  401. void sigint_ent(void)
  402. {
  403.     signal(SIGINT,(void (*)())sigint_ent);
  404. }
  405.  
  406.  
  407. int defline = 0;
  408. void setcon(int mode)    /* 画面情報設定 */
  409. {
  410. #ifdef FMR
  411.     int i;
  412.     int n;
  413.     if(vrammode >= 2) n = 10;
  414.     else              n = KEYMAX;
  415.  
  416.     for(i=0;i<n;i++) {    /* PFキー登録文字退避 */
  417.         regs.h.ah = 0x0f;
  418.         regs.h.dh = 0x80;
  419.         regs.h.dl = keysettbl[i*2];
  420.         regs.x.di = (unsigned)&keygettbl[i][2];
  421.         keygettbl[i][2] = 15;
  422.         xint90x();
  423.         keygettbl[i][0] = regs.h.al;
  424.         keygettbl[i][1] = regs.h.cl;
  425.     }
  426.     for(i=0;i<n;i++) {    /* PFキー文字登録 */
  427.         pfkeyset[0] = 0xff;
  428.         pfkeyset[1] = keysettbl[i*2+1];
  429.         regs.x.ax = 0x0e00;
  430.         regs.x.cx = 0x0002;
  431.         regs.h.dh = 0x80;
  432.         regs.h.dl = keysettbl[i*2];
  433.         regs.x.di = (unsigned)pfkeyset;
  434.         xint90x();
  435.     }
  436.     if(vrammode != 2) {
  437.         for(i=0;i<KEY2MAX;i++) {    /* 編集キー登録文字退避 */
  438.             regs.h.ah = 0x0f;
  439.             regs.h.dh = 0x00;
  440.             regs.h.dl = keyset2tbl[i*2];
  441.             regs.x.di = (unsigned)&keyget2tbl[i][2];
  442.             keyget2tbl[i][2] = 7;
  443.             xint90x();
  444.             keyget2tbl[i][0] = regs.h.al;
  445.             keyget2tbl[i][1] = regs.h.cl;
  446.         }
  447.         for(i=0;i<KEY2MAX;i++) {    /* 編集キー文字登録 */
  448.             regs.x.ax = 0x0e00;
  449.             regs.x.cx = 0x0001;
  450.             regs.h.dh = 0x00;
  451.             regs.h.dl = keyset2tbl[i*2];
  452.             regs.x.di = (unsigned)&keyset2tbl[i*2+1];
  453.             xint90x();
  454.         }
  455.     }
  456.     regs.h.ah = 0x05;
  457.     regs.x.di = (unsigned)machineinfo;
  458.     xint86x(0xaf);
  459.     defline = 20;
  460.     switch(vrammode) {
  461.     case 3:
  462.     case 0:    dispmode = 0;
  463.             break;
  464.     default:
  465.             if(machineinfo[3] & 2) dispmode = 1;
  466.             else dispmode = 2;
  467.     }
  468.     printf("\033[=7l");        /* 最終桁でカーソル移動しない設定 */
  469. #endif
  470. #ifdef PC_98
  471.     unsigned char far *nec_biosflag = (unsigned char far *)0x000501L;
  472.  
  473.   #ifdef PC88VA
  474.     if (vrammode == 3 || (vrammode == 0 && Va_ChkVA())) {
  475.         vrammode = 3;
  476.         vramadr = 0xa000;
  477.         vramatr = 0xa800;
  478.         defline = 20;
  479.         saveMseMode = Va_GetMseMode();
  480.         Va_SetMseMode(VA_STD);
  481.         dflt_atr = 0x70;
  482.         atr = 0x70;
  483.         Va_FuncKeySw(1);
  484.     } else
  485.   #endif
  486.     if((vrammode == 1) || (!vrammode && (*nec_biosflag & 8))) {
  487.         vramadr = 0xe000;
  488.         vramatr = 0xe200;
  489.         vrammode = 1;
  490.         defline = 25;
  491.     }
  492.     else {
  493.         vramadr = 0xa000;
  494.         vramatr = 0xa200;
  495.         vrammode = 0;
  496.         defline = 20;
  497.     }
  498.     printf("\033[>1h");        /* PFキー文字表示無し設定 */
  499. #endif
  500. #ifdef PC_AT
  501.     defline = 0;
  502.     dispmode = vrammode;
  503.     if(vrammode == J3100) dispmode = AT;
  504.     if(dispmode == DOSV) {
  505.         regs.h.ah = 0xfe; /* 疑似ビデオ・バッファ アドレス の取得 */
  506.         xint86x(0x10);
  507.         vramadr = sregs.es;
  508.     }
  509.     else vramadr = 0xb800;
  510.     regs.h.ah = 0x0f;
  511.     xint86(0x10);
  512.     actpage = regs.h.bh;
  513.     regs.h.ah = 0x03;
  514.     xint86(0x10);
  515.     cslmode = regs.x.cx;
  516.     if(vrammode == J3100) {    /* スクロールモード退避&高速スクロールセット */
  517.         regs.x.ax = 0x8200;
  518.         regs.h.bl = -1;
  519.         xint86(0x10);
  520.         sclmode = regs.h.al;
  521.         regs.x.ax = 0x8200;
  522.         regs.h.bl = 0;
  523.         xint86(0x10);
  524.     }
  525. #endif
  526.     if(strlen(ESCin)) printf(ESCin);    /* ESC0出力 */
  527.     if(!mode) {
  528.         regs.x.ax = 0x3300;
  529.         xintdos();
  530.         ctlcsave = regs.h.dl;
  531.         savesignal = signal(SIGINT,(void (*)())sigint_ent);
  532.     }
  533.     deforutoiro();
  534.     regs.x.ax = 0x3301;
  535.     regs.h.dl = 0x00;
  536.     xintdos();
  537. }
  538.  
  539. void restorecon(int mode)    /* 画面情報復帰 */
  540. {
  541. #ifdef FMR
  542.     int i;
  543.     int n;
  544.     if(vrammode == 2) n = 10;
  545.     else              n = KEYMAX;
  546.  
  547.     for(i=0;i<n;i++) {    /* PFキー文字復帰 */
  548.         regs.h.ah = 0x0e;
  549.         regs.h.al = keygettbl[i][0];
  550.         regs.h.ch = 0x00;
  551.         regs.h.cl = keygettbl[i][1];
  552.         regs.h.dh = 0x80;
  553.         regs.h.dl = keysettbl[i*2];
  554.         regs.x.di = (unsigned)&keygettbl[i][3];
  555.         xint90x();
  556.     }
  557.     if(vrammode != 2) {
  558.         for(i=0;i<KEY2MAX;i++) {    /* 編集キー文字復帰 */
  559.             regs.h.ah = 0x0e;
  560.             regs.h.al = keyget2tbl[i][0];
  561.             regs.h.ch = 0x00;
  562.             regs.h.cl = keyget2tbl[i][1];
  563.             regs.h.dh = 0x00;
  564.             regs.h.dl = keyset2tbl[i*2];
  565.             regs.x.di = (unsigned)&keyget2tbl[i][3];
  566.             xint90x();
  567.         }
  568.     }
  569.     printf("\033[=7h");        /* 最終桁でカーソル移動する設定 */
  570. #endif
  571. #ifdef PC_98
  572.   #ifdef PC88VA
  573.     if (vrammode == 3) {
  574.         Va_SetMseMode(saveMseMode);
  575.         Va_FuncKeySw(0);
  576.     }
  577.   #else
  578.     int i;
  579.     if(!vrammode && line > 25) {
  580.         loc(1,line);
  581.         for(i=0;i<80;i++) print(" ");
  582.     }
  583.   #endif
  584.     printf("\033[>1l");        /* PFキー文字表示有り設定 */
  585. #endif
  586. #ifdef PC_AT
  587.     regs.h.ah = 0x01;
  588.     regs.x.cx = cslmode;
  589.     xint86(0x10);
  590.     if(vrammode == J3100) {    /* スクロールモード復元 */
  591.         regs.x.ax = 0x8200;
  592.         regs.h.bl = sclmode;
  593.         xint86(0x10);
  594.     }
  595. #endif
  596.     if(strlen(ESCout)) printf(ESCout);    /* ESC1出力 */
  597.     if(!mode) {
  598.         signal(SIGINT,savesignal);
  599.         regs.h.dl = ctlcsave;
  600.     }
  601.     else       regs.h.dl = 0x00;
  602.     regs.x.ax = 0x3301;
  603.     xintdos();
  604. }
  605.  
  606. void cslon(void)            /* カーソル表示 */
  607. {
  608. #ifdef FMR
  609.     regs.h.ah = 0x0c;
  610.     xint91();
  611.     if(!regs.h.al)
  612.         return;
  613.     regs.x.ax = 0x0b00;
  614.     xint91();
  615. #endif
  616. #ifdef PC_98
  617.     regs.h.ah = 0x11;
  618.     xint86(0x18);
  619. #endif
  620. #ifdef PC_AT
  621.     regs.h.ah = 0x01;
  622.     regs.x.cx = 0x0607;
  623.     xint86(0x10);
  624. #endif
  625. }
  626.  
  627. void csloff(void)            /* カーソル非表示 */
  628. {
  629. #ifdef FMR
  630.     regs.h.ah = 0x0c;
  631.     xint91();
  632.     if(regs.h.al == 1)
  633.         return;
  634.     regs.x.ax = 0x0b01;
  635.     xint91();
  636. #endif
  637. #ifdef PC_98
  638.     regs.h.ah = 0x12;
  639.     xint86(0x18);
  640. #endif
  641. #ifdef PC_AT
  642.     regs.h.ah = 0x01;
  643.     regs.x.cx = cslmode | 0x2000;
  644.     xint86(0x10);
  645. #endif
  646. }
  647.  
  648. void chglowline(void)        /* 20/25行画面設定 */
  649. {
  650. #ifdef FMR
  651.     printf("\033[=3l");
  652. #endif
  653. #ifdef PC_98
  654.   #ifdef PC88VA
  655.     if(vrammode != 1) printf("\033[>3h");
  656.   #else
  657.     if(vrammode == 0) printf("\033[>3h");
  658.   #endif
  659.     else {
  660.         regs.x.ax = 0x0a00;
  661.         xint86(0x18);
  662.     }
  663. #endif
  664.     allclr();
  665.     return;
  666. }
  667.  
  668. void chghighline(void)        /* 25/31行画面設定 */
  669. {
  670. #ifdef FMR
  671.     printf("\033[=2l");
  672. #endif
  673. #ifdef PC_98
  674.   #ifdef PC88VA
  675.     if(vrammode != 1) printf("\033[>3l");
  676.   #else
  677.     if(vrammode == 0) printf("\033[>3l");
  678.   #endif
  679.     else {
  680.         regs.x.ax = 0x0a10;
  681.         xint86(0x18);
  682.     }
  683. #endif
  684.     return;
  685. }
  686.  
  687. void clr(void)                /* カーソル以下画面クリア */
  688. {
  689. #ifdef PC_AT
  690.     if(dispmode == DOSV) printf("\033[K");
  691.     else                 printf("\033[2K");
  692. #else
  693.     printf("\033[2K");
  694. #endif
  695. }
  696.  
  697. void clr1(char atr)            /* 行クリア */
  698. {
  699.     iro(atr);
  700.     print(space);
  701.     deforutoiro();
  702. }
  703.  
  704. void clr2(void)                /* カーソル以下画面クリア(VRAMモード=3専用) */
  705. {
  706. #ifdef FMR
  707.     if(vrammode == 3) printf("\033[2K");
  708. #endif
  709. #ifdef PC_AT
  710.     if(vrammode == J3100) printf("\033[2K");
  711. #endif
  712.     return;
  713. }
  714.  
  715. void allclr(void)            /* 全画面クリア */
  716. {
  717.     deforutoiro();
  718. #ifdef FMR
  719.     regs.h.ah = 0x02;
  720.     xint91();
  721. #else /* not FMR */
  722.     printf("\033[2J");
  723. #endif
  724.     csloff();
  725. }
  726.  
  727. void setline(int l)            /* 画面行数設定 */
  728. {
  729. #ifdef FMR
  730.     regs.x.ax = 0x0401;
  731.     xint90();
  732. #endif
  733.     if(l && l == defline) chglowline();
  734.     else                  chghighline();
  735. #ifdef FMR
  736.     regs.x.ax = 0x0400;
  737.     xint90();
  738. #endif
  739.     csloff();
  740. }
  741.  
  742. char atrt[4];
  743. static char save_color;
  744. void atrset(char color)        /* 画面アトリビュート設定 */
  745. {
  746. #ifdef FMR
  747.     char r;
  748.  
  749.     save_color = color;
  750.     r = color & 0x38;
  751.     if(r & 0x20) r |= 0x80;
  752.     color &= 0x07;
  753.     switch(dispmode) {
  754.     case 0: atrt[0] = 0;
  755.             atrt[1] = r;
  756.             atrt[2] = color;
  757.             atrt[3] = 0;
  758.             regs.h.ah = 0x11;
  759.             regs.x.di = (unsigned)atrt;
  760.             xint91x();
  761.             break;
  762.     case 1:    atr1 = (int)((r << 8) & 0x3f00) | color;
  763.             if(r & 0x20) atr1 |= 0x08;
  764.             break;
  765.     case 2:    atr1 = (int)(r & 0x38) | color;
  766.     }
  767. #endif
  768. #ifdef PC_98
  769.     save_color = color;
  770.   #ifdef PC88VA
  771.     if (vrammode == 3)
  772.         atr = (color & 7) * 0x10;
  773.     else
  774.   #endif
  775.     atr = ((color & 7) * 32)+1;
  776.     if(color & 0x08) atr |= 0x04;
  777.     if(color & 0x10) atr |= 0x02;
  778.     if(color & 0x20) atr |= 0x08;
  779. #endif
  780. #ifdef PC_AT
  781.     save_color = color;
  782.     if(dispmode != DOSV) {
  783.         atr = color & 7;
  784.         switch(atr) {
  785.         case 2: atr = 4;break;
  786.         case 3: atr = 5;break;
  787.         case 4: atr = 2;break;
  788.         case 5: atr = 3;break;
  789.         }
  790.         if(color & 0x08) atr <<= 4;
  791.         if(color & 0x20) atr |= 0x88;
  792.     }
  793.     else atr = color;
  794. #endif
  795. }
  796.  
  797. void iro(char colorno)        /* 画面色属性設定 */
  798. {
  799.     atrset(irotbl[colorno]);
  800. }
  801.  
  802. void deforutoiro(void)        /* デフォルト色属性設定 */
  803. {
  804.     iro(IETC);
  805. }
  806.  
  807. static void vputc(unsigned c)    /* 画面1文字表示 */
  808. {
  809. #ifdef FMR
  810.     int far *ap;
  811.     int far *atrp;
  812.     char far *ap1;
  813.  
  814.     switch(dispmode) {
  815.     case 0:    regs.x.ax = 0x1300;
  816.             regs.h.bh = 0x00;
  817.             regs.h.bl = c;
  818.             regs.h.dh = gyo;
  819.             regs.h.dl = keta;
  820.             int86(0x91,®s,®s);
  821.             break;
  822.     case 1:    ap = (int far *)MK_FP(0xf800,vramoffset);
  823.             atrp = (int far *)MK_FP(0xfa00,vramoffset);
  824.             *ap = c;
  825.             *atrp = (int)atr1;
  826.             break;
  827.     case 2:    ap1 = (char far *)MK_FP(0xc800,vramoffset);
  828.             *ap1 = c;
  829.             *(ap1+1) = atr1;
  830.     }
  831.     keta++;
  832.     vramoffset += 2;
  833. #endif
  834. #ifdef PC_98
  835.     int far *ap;
  836.     int far *atrp;
  837.  
  838.     ap = (int far *)MK_FP(vramadr,vramoffset);
  839.     atrp = (int far *)MK_FP(vramatr,vramoffset);
  840.     *ap = c;
  841.     *atrp = (int)atr;
  842.     if(!vrammode && vramoffset >= 0x1220) {
  843.         ap = (int far *)MK_FP(vramadr,vramoffset+0x1f40-0x1220);
  844.         atrp = (int far *)MK_FP(vramatr,vramoffset+0x1f40-0x1220);
  845.         *ap = c;
  846.         *atrp = (int)atr;
  847.     }
  848.     keta++;
  849.     vramoffset += 2;
  850. #endif
  851. #ifdef PC_AT
  852.     int far *ap;
  853.  
  854.     switch(dispmode) {
  855.     case AT:    regs.h.ah = 0x02;
  856.                 regs.h.bh = actpage;
  857.                 regs.h.dh = gyo-1;
  858.                 regs.h.dl = keta-1;
  859.                 xint86(0x10);
  860.                 regs.h.ah = 0x09;
  861.                 regs.h.al = c;
  862.                 regs.h.bh = actpage;
  863.                 regs.h.bl = atr;
  864.                 regs.x.cx = 1;
  865.                 xint86(0x10);
  866.                 break;
  867.     case AX:    ap = (int far *)MK_FP(vramadr,vramoffset);
  868.                 *ap = c | (atr * 0x100);
  869.                 break;
  870.     case DOSV:    ap = (int far *)MK_FP(vramadr,vramoffset);
  871.                 *ap = c | (atr * 0x100);
  872.                 break;
  873.     }
  874.     keta++;
  875.     vramoffset += 2;
  876. #endif
  877. }
  878.  
  879. /*
  880. static void vputw(unsigned w)    * 画面2文字表示 *
  881. {
  882. #ifdef FMR
  883.     char far *ap1;
  884.     int a;
  885.     char b,c;
  886.  
  887.     switch(dispmode) {
  888.     case 0:    regs.x.ax = 0x1300;
  889.             regs.h.bh = 0x01;
  890.             regs.h.bl = w/256;
  891.             regs.h.dh = gyo;
  892.             regs.h.dl = keta;
  893.             int86(0x91,®s,®s);
  894.             regs.x.ax = 0x1300;
  895.             regs.h.bh = 0x03;
  896.             regs.h.bl = w & 0xff;
  897.             regs.h.dh = gyo;
  898.             regs.h.dl = keta+1;
  899.             int86(0x91,®s,®s);
  900.             keta += 2;
  901.             if(keta > 80) {
  902.                 keta = 1;
  903.                 gyo++;
  904.             }
  905.             break;
  906.     case 1:    a = w;
  907.             vputc(a | 0x8000);
  908.             vputc(a | 0x8080);
  909.             break;
  910.     case 2:    b = w & 0xff;
  911.             c = w / 256;
  912.             ap1 = (char far *)MK_FP(0xc800,vramoffset);
  913.             *(ap1+1) = (char)(atr1 | 0x40);
  914.             *(ap1+3) = (char)(atr1 & 0xbf);
  915.             ap1 = (char far *)MK_FP(0xca00,vramoffset);
  916.             *ap1 = c;
  917.             *(ap1+1) = b;
  918.             *(ap1+2) = c;
  919.             *(ap1+3) = b;
  920.             keta += 2;
  921.             if(keta > 80) {
  922.                 keta = 1;
  923.                 gyo++;
  924.             }
  925.             vramoffset += 4;
  926.     }
  927. #endif
  928. #ifdef PC_98
  929.     int a;
  930.  
  931.     a = (w & 0xff)*256 + w/256;
  932.     a -= 0x20;
  933.     vputc(a);
  934.       a |= 0x8080;
  935.     vputc(a);
  936. #endif
  937. #ifdef PC_AT
  938.     vputc(w/256);
  939.     vputc(w&0xff);
  940. #endif
  941. }
  942. */
  943.  
  944. static char xbuf[81];
  945. void print(char *pt)        /* 画面表示 */
  946. {
  947.     int h,l;
  948.     int k = 0;
  949.     char scolor;
  950. #ifdef FMR
  951.     char far *ap1;
  952.     char *out,c;
  953. #endif
  954. #ifdef PC_AT
  955.     char *out,c;
  956.     struct REGPACK regp;
  957.     long offset = vramoffset;
  958. #else
  959.     int a;
  960. #endif
  961. #ifdef FMR
  962.     if(vrammode == 3) {
  963.         for(k=0,out = xbuf;c=*pt;pt++) {
  964.             if(c == '\t') {
  965.                 if(bunmode && tabcrmode == 2) {
  966.                     *out++ = '・';
  967.                     keta++;
  968.                     for(;(keta-1)%(tabno);) {
  969.                         *out++ = '.';
  970.                         keta++;
  971.                     }
  972.                 }
  973.                 else {
  974.                     *out++ = ' ';
  975.                     keta++;
  976.                     for(;(keta-1)%(tabno);) {
  977.                         *out++ = ' ';
  978.                         keta++;
  979.                     }
  980.                 }
  981.                 continue;
  982.             }
  983.             if(c == '\n') {
  984.                 if(tabcrmode) k = 1;
  985.                 break;
  986.             }
  987.             if(iskanji(c) && iskanji2(*(pt+1))) {
  988.                 *out++ = c;
  989.                 *out++ = *(++pt);
  990.                 keta += 2;
  991.                 continue;
  992.             }
  993.             if(c < ' ' || c > '゚') c = ' ';
  994.             *out++ = c;
  995.             keta++;
  996.         }
  997.         *out = 0;
  998.         regs.h.ah = 0x1e;
  999.         regs.x.cx = strlen(xbuf);
  1000.         regs.x.di = (unsigned)xbuf;
  1001.         int86x(0x91,®s,®s,&sregs);
  1002.         if(k) {
  1003.             vputc(RTN_CODE);
  1004.         }
  1005.         return;
  1006.     }
  1007. #endif
  1008. #ifdef PC_AT
  1009.     if(vrammode == J3100) {
  1010.         h = keta;
  1011.         for(k=0,out = xbuf;c=*pt;pt++) {
  1012.             if(c == '\t') {
  1013.                 if(bunmode && tabcrmode == 2) {
  1014.                     *out++ = '・';
  1015.                     keta++;
  1016.                     for(;(keta-1)%(tabno);) {
  1017.                         *out++ = '.';
  1018.                         keta++;
  1019.                     }
  1020.                 }
  1021.                 else {
  1022.                     *out++ = ' ';
  1023.                     keta++;
  1024.                     for(;(keta-1)%(tabno);) {
  1025.                         *out++ = ' ';
  1026.                         keta++;
  1027.                     }
  1028.                 }
  1029.                 continue;
  1030.             }
  1031.             if(c == '\n') {
  1032.                 if(tabcrmode) k = 1;
  1033.                 break;
  1034.             }
  1035.             if(iskanji(c) && iskanji2(*(pt+1))) {
  1036.                 *out++ = c;
  1037.                 *out++ = *(++pt);
  1038.                 keta += 2;
  1039.                 continue;
  1040.             }
  1041.             if(c < ' ' || c > '゚') c = ' ';
  1042.             *out++ = c;
  1043.             keta++;
  1044.         }
  1045.         *out = 0;
  1046.         regp.r_dx = (gyo-1)*256+(h-1);
  1047.         regp.r_ax = 0x1300;
  1048.         regp.r_bx = actpage*256+atr;
  1049.         regp.r_cx = strlen(xbuf);
  1050.         regp.r_bp = (unsigned)xbuf;
  1051.         regp.r_es = sregs.ds;
  1052.         intr(0x10,®p);
  1053.         if(k) {
  1054.             vputc(RTN_CODE);
  1055.         }
  1056.         return;
  1057.     }
  1058. #endif
  1059.     scolor = save_color;
  1060.     for(;h=(int)*pt;pt++) {
  1061.         if(h == '\t') {
  1062.             if(bunmode && tabcrmode == 2) {
  1063.                 iro(ITAB);
  1064.                 vputc(TAB_CODE);
  1065.                 k++;
  1066.                 for(;(keta-1)%(tabno);) {
  1067.                     vputc('.');
  1068.                     k++;
  1069.                 }
  1070.                 atrset(scolor);
  1071.             }
  1072.             else {
  1073.                 vputc(' ');
  1074.                 k++;
  1075.                 for(;(keta-1)%(tabno);) {
  1076.                     vputc(' ');
  1077.                     k++;
  1078.                 }
  1079.             }
  1080.             continue;
  1081.         }
  1082.         if(h == '\n') {
  1083.             if(bunmode && tabcrmode) {
  1084.                 iro(ICR);
  1085. #ifdef PC_AT
  1086.             if(dispmode != AX)    vputc(RTN_CODE);
  1087.             else                vputc(RTNAX_CODE);
  1088. #else
  1089.                 vputc(RTN_CODE);
  1090. #endif
  1091.                 k++;
  1092.                 atrset(scolor);
  1093.             }
  1094.             else {
  1095.                 vputc(' ');
  1096.                 k++;
  1097.             }
  1098.             for(;keta <= 80;) {
  1099.                 vputc(' ');
  1100.                 k++;
  1101.             }
  1102.             continue;
  1103.         }
  1104.         if(iskanji(h) && iskanji2(*(pt+1))) {
  1105.             l = (int)*(++pt);
  1106. #ifndef PC_AT
  1107.             h -= (h <= 0x9f) ? 0x71 : 0xb1;
  1108.             h = (h << 1) + 1;
  1109.             if(l > 0x7f) l--;
  1110.             if(l >= 0x9e) {
  1111.                 l -= 0x7d;
  1112.                 h++;
  1113.             }
  1114.             else l -= 0x1f;
  1115. #endif
  1116. #ifdef FMR
  1117.             switch(dispmode) {
  1118.             case 0:    regs.x.ax = 0x1300;
  1119.                     regs.h.bh = 0x01;
  1120.                     regs.h.bl = h;
  1121.                     regs.h.dh = gyo;
  1122.                     regs.h.dl = keta;
  1123.                     int86(0x91,®s,®s);
  1124.                     regs.x.ax = 0x1300;
  1125.                     regs.h.bh = 0x03;
  1126.                     regs.h.bl = l;
  1127.                     regs.h.dh = gyo;
  1128.                     regs.h.dl = keta+1;
  1129.                     int86(0x91,®s,®s);
  1130.                     keta += 2;
  1131.                     break;
  1132.             case 1:    a = (h*256 + l);
  1133.                     vputc(a | 0x8000);
  1134.                     vputc(a | 0x8080);
  1135.                     break;
  1136.             case 2:    ap1 = (char far *)MK_FP(0xc800,vramoffset);
  1137.                     *(ap1+1) = (char)(atr1 | 0x40);
  1138.                     *(ap1+3) = (char)(atr1 & 0xbf);
  1139.                     ap1 = (char far *)MK_FP(0xca00,vramoffset);
  1140.                     *ap1 = h;
  1141.                     *(ap1+1) = l;
  1142.                     *(ap1+2) = h;
  1143.                     *(ap1+3) = l;
  1144.                     keta += 2;
  1145.                     vramoffset += 4;
  1146.             }
  1147. #endif
  1148. #ifdef PC_98
  1149.             a = (l)*256 + h;
  1150.             a -= 0x20;
  1151.             vputc(a);
  1152.               a |= 0x8080;
  1153.             vputc(a);
  1154. #endif
  1155. #ifdef PC_AT
  1156.             vputc(h);
  1157.             vputc(l);
  1158.             k += 2;
  1159. #endif
  1160.             continue;
  1161.         }
  1162.         if(h < ' ' || h > '゚') h = ' ';
  1163.         vputc(h);
  1164.         k++;
  1165.     }
  1166. #ifdef PC_AT
  1167.     if(dispmode == DOSV)
  1168.         dosv_disp(offset,k);
  1169. #endif
  1170. }
  1171.  
  1172. int keycheck(void)        /* キー入力チェック */
  1173. {
  1174. #ifdef FMR
  1175.     regs.h.ah = 0x07;
  1176.     xint90();            /* キー入力チェック */
  1177.     if(regs.h.dh == 0xff) {
  1178.         return(0);
  1179.     }
  1180. #endif
  1181. #ifdef PC_98
  1182.     regs.h.ah = 0x01;
  1183.     xint86(0x18);        /* キー入力チェック */
  1184.     if(!regs.h.bh) {
  1185.         return(0);
  1186.     }
  1187. #endif
  1188. #ifdef PC_AT
  1189.     if(dispmode) regs.h.ah = 0x11;
  1190.     else         regs.h.ah = 0x01;
  1191.     xint86(0x16);        /* キー入力チェック */
  1192.     if(regs.x.flags & 0x40) {
  1193.         return(0);
  1194.     }
  1195. #endif
  1196.     return(1);
  1197. }
  1198.  
  1199. void keyget(void)        /* キー押下待ち */
  1200. {
  1201.     regs.x.ax = 0x0cff;
  1202.     xintdos();
  1203.  
  1204. #ifdef FMR
  1205.     regs.x.ax = 0x0900;
  1206.     xint90();
  1207. #endif
  1208. #ifdef PC_98
  1209.     regs.h.ah = 0x00;
  1210.     xint86(0x18);
  1211. #endif
  1212. #ifdef PC_AT
  1213.     regs.h.ah = 0x00;
  1214.     xint86(0x16);
  1215. #endif
  1216.     regs.x.ax = 0x0cff;
  1217.     xintdos();
  1218. }
  1219.  
  1220. static void jikokusub(int mode)
  1221. {
  1222.     char buf[12];
  1223.     struct tm *jtime;
  1224.  
  1225.     jtime = localtime(lsavetime);
  1226.     if(mode) {
  1227.         sprintf(buf,"%02d:%02d:%02d  ",
  1228.         jtime->tm_hour,jtime->tm_min,jtime->tm_sec);
  1229.     }
  1230.     else {
  1231.         if(jtime->tm_hour < 12)
  1232.             sprintf(buf,"%02d:%02d:%02dAM",
  1233.             jtime->tm_hour,jtime->tm_min,jtime->tm_sec);
  1234.         else
  1235.             sprintf(buf,"%02d:%02d:%02dPM",
  1236.             jtime->tm_hour-12,jtime->tm_min,jtime->tm_sec);
  1237.     }
  1238.     print(buf);
  1239. }
  1240.  
  1241. static time_t sv_time[1];
  1242. static void jikokudisp(int mode,int mode2)
  1243. {
  1244.     time_t ltime[1];
  1245.     char a;
  1246.  
  1247.     time(ltime);
  1248.     if(mode) {
  1249.         if(lsavetime[0] == ltime[0]) return;
  1250.     }
  1251.     if((mode2 == 1) && ltime[0] >= sv_time[0]+waittimes) {
  1252.         hpread(titlecount,3);
  1253.         ttail = p_tail;
  1254.         sv_time[0] = ltime[0];
  1255.     }
  1256.     if(mode2 == 2) {
  1257. #ifdef FMR
  1258.         regs.h.ah = 0x08;
  1259.         xint90();
  1260.         a = regs.h.al & 0x04;
  1261. #endif
  1262. #ifdef PC_98
  1263.         regs.h.ah = 0x02;
  1264.         xint86(0x18);
  1265.         a = regs.h.al & 0x01;
  1266. #endif
  1267. #ifdef PC_AT
  1268.         regs.h.ah = 0x02;
  1269.         xint86(0x16);
  1270.         a = regs.h.al & 0x03;
  1271. #endif
  1272.         if((!a && (ltime[0] >= sv_time[0]+autodisptime))
  1273.          || (a && (ltime[0] >= sv_time[0]+autodisptime/5))) {
  1274.             autodispsw = 1;
  1275.             sv_time[0] = ltime[0];
  1276.         }
  1277.     }
  1278.     lsavetime[0] = ltime[0];
  1279.     loc(71,1);iro(IJIKOKU);
  1280.     switch(jikokumode) {
  1281.     case 0: if(!mode) iro(ITITLE); print("          "); break;
  1282.     case 1: jikokusub(1); break;
  1283.     default:jikokusub(0); break;
  1284.     }
  1285.     deforutoiro();
  1286. }
  1287.  
  1288. static void pfdispsub(char *buf,int i,int mode)    /* PFキー表示サブ */
  1289. {
  1290.     char *s;
  1291.     int k;
  1292.  
  1293. #ifdef FMR
  1294.     if(mode != 3) k = keytbl[0x81 + mode*0x20 + i-1];
  1295.     else          k = keytbl[0xf5 + i-1];
  1296.  
  1297.     s = "     ";
  1298.     if(mode != 4) {
  1299.         switch(k) {
  1300.         case 0x81: s = " 終了";break;
  1301.         case 0x82: s = " トップ";break;
  1302.         case 0x83: s = " ラスト ";break;
  1303.         case 0x84: s = " ヘルプ";break;
  1304.         case 0x85: s = " 切出";break;
  1305.         case 0x86: s = " 削除";break;
  1306.         case 0x87: s = " コピー";break;
  1307.         case 0x88: s = " 検索";break;
  1308.         case 0x89: s = " ID";break;
  1309.         case 0x8a: if(nifmode == NFNORMAL) s = " コメント";
  1310.                    else                       s = " ノーマル";
  1311.                    break;
  1312.         case 0xa1: s = " DOS ";break;
  1313.         case 0xa2: if(tmode) s = "<ファイル";
  1314.                    else         s = " 前項";
  1315.                    break;
  1316.         case 0xa3: if(tmode) s = "ファイル>";
  1317.                    else      s = " 次項";
  1318.                    break;
  1319.         case 0xa4: if(tmode) s = "ファイル#";break;
  1320.         case 0xa5: s = " 取消";break;
  1321.         case 0xa6: s = "削キャン";break;
  1322.         case 0xa7: s = "タグ設";break;
  1323.         case 0xa8: s = "タグ←";break;
  1324.         case 0xa9: s = "タグ→";break;
  1325.         case 0xaa: s = " 発言";break;
  1326.         case 0xc1: if(tmode) s = " 書終";break;
  1327.         case 0xc2: s = " タイトル";break;
  1328.         case 0xc3: s = "<検索";break;
  1329.         case 0xc4: s = "検索>";break;
  1330.         case 0xc5: s = " 印刷";break;
  1331.         case 0xc6: if(tmode) s = "ログ大";break;
  1332.         case 0xc7: if(tmode) s = "ログ詳";break;
  1333.         case 0xc8: s = "20/25";break;
  1334.         case 0xc9: s = " ユーザ";break;
  1335.         case 0xca: s = "オート表";break;
  1336.         case 0xf5: if(tmode) s = "キャン終";break;
  1337.         case 0xf6: s = " +10 ";break;
  1338.         case 0xf7: s = " +20 ";break;
  1339.         case 0xf8: s = " +50 ";break;
  1340.         case 0xf9: s = "既セット";break;
  1341.         case 0xfa: s = "既キャン";break;
  1342.         case 0xfb: s = "JUMP@";break;
  1343.         case 0xfc: if(tmode) s = " TYPE";break;
  1344.         case 0xfd: s = "コメ+ID";break;
  1345.         case 0xfe: s = "発言2";break;
  1346.         }
  1347.     }
  1348.     if(i == 10) i = 0;
  1349.     sprintf(buf,"%d%s",i,s);
  1350. #endif
  1351. #ifdef PC_98
  1352.     if(mode != 3) k = keytbl[0x81 + mode*0x20 + i-1];
  1353.     else          k = keytbl[0xf5 + i-1];
  1354.  
  1355.     s = "     ";
  1356.     if(mode != 4) {
  1357.         switch(k) {
  1358.         case 0x81: s = "終了 ";break;
  1359.         case 0x82: s = "トップ ";break;
  1360.         case 0x83: s = " ラスト ";break;
  1361.         case 0x84: s = "ヘルプ ";break;
  1362.         case 0x85: s = "切出 ";break;
  1363.         case 0x86: s = "削除 ";break;
  1364.         case 0x87: s = "コピー ";break;
  1365.         case 0x88: s = "検索 ";break;
  1366.         case 0x89: s = "ID ";break;
  1367.         case 0x8a: if(nifmode == NFNORMAL) s = "コメント ";
  1368.                    else                       s = "ノーマル ";
  1369.                    break;
  1370.         case 0xa1: s = " DOS ";break;
  1371.         case 0xa2: if(tmode) s = "<ファイル";
  1372.                    else         s = "前項 ";
  1373.                    break;
  1374.         case 0xa3: if(tmode) s = "ファイル>";
  1375.                    else         s = "次項 ";
  1376.                    break;
  1377.         case 0xa4: if(tmode) s = "ファイル#";break;
  1378.         case 0xa5: s = " 取消";break;
  1379.         case 0xa6: s = "削キャン";break;
  1380.         case 0xa7: s = "タグ設";break;
  1381.         case 0xa8: s = "タグ←";break;
  1382.         case 0xa9: s = "タグ→";break;
  1383.         case 0xaa: s = "発言 ";break;
  1384.         case 0xc1: if(tmode) s = "書終 ";break;
  1385.         case 0xc2: s = "タイトル ";break;
  1386.         case 0xc3: s = "<検索";break;
  1387.         case 0xc4: s = "検索>";break;
  1388.         case 0xc5: s = "印刷 ";break;
  1389.         case 0xc6: if(tmode) s = "ログ大";break;
  1390.         case 0xc7: if(tmode) s = "ログ詳";break;
  1391.     #ifdef PC88VA
  1392.         case 0xc8: if(vrammode != 1) s = "20/25";
  1393.     #else
  1394.         case 0xc8: if(vrammode == 0) s = "20/25";
  1395.     #endif
  1396.                    else                 s = "25/31";
  1397.                    break;
  1398.         case 0xc9: s = "ユーザ ";break;
  1399.         case 0xca: s = "オート表";break;
  1400.         case 0xf5: if(tmode) s = "キャン終";break;
  1401.         case 0xf6: s = " +10 ";break;
  1402.         case 0xf7: s = " +20 ";break;
  1403.         case 0xf8: s = " +50 ";break;
  1404.         case 0xf9: s = "既セット";break;
  1405.         case 0xfa: s = "既キャン";break;
  1406.         case 0xfb: s = "JUMP@";break;
  1407.         case 0xfc: if(tmode) s = "TYPE ";break;
  1408.         case 0xfd: s = "コメ+ID";break;
  1409.         case 0xfe: s = "発言2";break;
  1410.         }
  1411.     }
  1412.     if(i == 10) i = 0;
  1413.     sprintf(buf,"%d %s",i,s);
  1414. #endif
  1415. #ifdef PC_AT
  1416.     if(mode != 3) k = keytbl[0x81 + mode*0x20 + i-1];
  1417.     else          k = keytbl[0xf5 + i-1];
  1418.  
  1419.     s = "     ";
  1420.     if(mode != 4) {
  1421.         switch(k) {
  1422.         case 0x81: s = " 終了";break;
  1423.         case 0x82: s = " トップ";break;
  1424.         case 0x83: s = " ラスト ";break;
  1425.         case 0x84: s = " ヘルプ";break;
  1426.         case 0x85: s = " 切出";break;
  1427.         case 0x86: s = " 削除";break;
  1428.         case 0x87: s = " コピー";break;
  1429.         case 0x88: s = " 検索";break;
  1430.         case 0x89: s = " ID";break;
  1431.         case 0x8a: if(nifmode == NFNORMAL) s = " コメント";
  1432.                    else                       s = " ノーマル";
  1433.                    break;
  1434.         case 0xa1: s = " DOS ";break;
  1435.         case 0xa2: if(tmode) s = "<ファイル";
  1436.                    else         s = " 前項";
  1437.                    break;
  1438.         case 0xa3: if(tmode) s = "ファイル>";
  1439.                    else      s = " 次項";
  1440.                    break;
  1441.         case 0xa4: if(tmode) s = "ファイル#";break;
  1442.         case 0xa5: s = " 取消";break;
  1443.         case 0xa6: s = "削キャン";break;
  1444.         case 0xa7: s = "タグ設";break;
  1445.         case 0xa8: s = "タグ←";break;
  1446.         case 0xa9: s = "タグ→";break;
  1447.         case 0xaa: s = " 発言";break;
  1448.         case 0xc1: if(tmode) s = " 書終";break;
  1449.         case 0xc2: s = " タイトル";break;
  1450.         case 0xc3: s = "<検索";break;
  1451.         case 0xc4: s = "検索>";break;
  1452.         case 0xc5: s = " 印刷";break;
  1453.         case 0xc6: if(tmode) s = "ログ大";break;
  1454.         case 0xc7: if(tmode) s = "ログ詳";break;
  1455.         case 0xc8: s = "     ";break;
  1456.         case 0xc9: s = " ユーザ";break;
  1457.         case 0xca: s = "オート表";break;
  1458.         case 0xf5: if(tmode) s = "キャン終";break;
  1459.         case 0xf6: s = " +10 ";break;
  1460.         case 0xf7: s = " +20 ";break;
  1461.         case 0xf8: s = " +50 ";break;
  1462.         case 0xf9: s = "既セット";break;
  1463.         case 0xfa: s = "既キャン";break;
  1464.         case 0xfb: s = "JUMP@";break;
  1465.         case 0xfc: if(tmode) s = " TYPE";break;
  1466.         case 0xfd: s = "コメ+ID";break;
  1467.         case 0xfe: s = "発言2";break;
  1468.         }
  1469.     }
  1470.     if(i == 10) i = 0;
  1471.     if(i < 11)
  1472.         sprintf(buf,"%d%s",i,s);
  1473.     else
  1474.         sprintf(buf," %s",s);
  1475. #endif
  1476. }
  1477.  
  1478. void pfdisp(int mode)    /* PFキー表示 */
  1479. {
  1480. #ifdef FMR
  1481.     switch(mode) {
  1482.     case 0:
  1483.         pftbl[0] = FP_OFF(pfdata);
  1484.         pftbl[1] = FP_SEG(pfdata);
  1485.         pftbl[2] = FP_OFF(pfatr);
  1486.         pftbl[3] = FP_SEG(pfatr);
  1487.         break;
  1488.     case 1:
  1489.         pftbl[0] = FP_OFF(pfsdata);
  1490.         pftbl[1] = FP_SEG(pfsdata);
  1491.         pftbl[2] = FP_OFF(pfsatr);
  1492.         pftbl[3] = FP_SEG(pfsatr);
  1493.         break;
  1494.     case 2:
  1495.         pftbl[0] = FP_OFF(pfcdata);
  1496.         pftbl[1] = FP_SEG(pfcdata);
  1497.         pftbl[2] = FP_OFF(pfcatr);
  1498.         pftbl[3] = FP_SEG(pfcatr);
  1499.         break;
  1500.     case 3:
  1501.         pftbl[0] = FP_OFF(pfscdata);
  1502.         pftbl[1] = FP_SEG(pfscdata);
  1503.         pftbl[2] = FP_OFF(pfscatr);
  1504.         pftbl[3] = FP_SEG(pfscatr);
  1505.         break;
  1506.     case 4:
  1507.         pftbl[0] = FP_OFF(pfadata);
  1508.         pftbl[1] = FP_SEG(pfadata);
  1509.         pftbl[2] = FP_OFF(pfaatr);
  1510.         pftbl[3] = FP_SEG(pfaatr);
  1511.         break;
  1512.     }
  1513.     regs.x.ax = 0x1f01;
  1514.     regs.x.cx = 70;
  1515.     regs.h.dl = 1;
  1516.     regs.x.di = (unsigned)pftbl;
  1517.     xint91x();
  1518. #endif
  1519. #ifdef PC_98
  1520.     int i,col;
  1521.     char c,*b;
  1522.  
  1523.     col = irotbl[IPFKEY] & 0x07;
  1524.     switch(mode) {
  1525.     case 0: b=pfdata;
  1526.             break;
  1527.     case 1: b=pfsdata;
  1528.             break;
  1529.     case 2: b=pfcdata;
  1530.             break;
  1531.     case 3: b=pfscdata;
  1532.             break;
  1533.     case 4: b=pfadata;
  1534.             break;
  1535.     }
  1536.     loc(1,line);
  1537.     atrset(col);
  1538.     c = *(b+3);
  1539.     *(b+3) = 0;
  1540.     print(b);
  1541.     b += 3;
  1542.     *b = c;
  1543.     for (i = 0; i < 10; i++) {
  1544.         atrset(col);
  1545.         if(i == 5) {
  1546.             c = *(b+4);
  1547.             *(b+4) = 0;
  1548.             print(b);
  1549.             b += 4;
  1550.         }
  1551.         else {
  1552.             c = *(b+1);
  1553.             *(b+1) = 0;
  1554.             print(b);
  1555.             b++;
  1556.         }
  1557.         *b = c;
  1558.         atrset(0x08 | col);
  1559.         c = *(b+6);
  1560.         *(b+6) = 0;
  1561.         print(b);
  1562.         b += 6;
  1563.         *b = c;
  1564.     }
  1565.     deforutoiro();
  1566. #endif
  1567. #ifdef PC_AT
  1568.     int i,col;
  1569.     char c,*b;
  1570.  
  1571.     col = irotbl[IPFKEY];
  1572.     switch(mode) {
  1573.     case 0: b=pfdata;
  1574.             break;
  1575.     case 1: b=pfsdata;
  1576.             break;
  1577.     case 2: b=pfcdata;
  1578.             break;
  1579.     case 3: b=pfscdata;
  1580.             break;
  1581.     case 4: b=pfadata;
  1582.             break;
  1583.     }
  1584.     loc(1,line);
  1585.     atrset(col);
  1586.     c = *(b+2);
  1587.     *(b+2) = 0;
  1588.     print(b);
  1589.     b += 2;
  1590.     *b = c;
  1591.     for (i = 0; i < 12; i++) {
  1592.         atrset(col);
  1593.         if(i == 4 || i == 8) {
  1594.             c = *(b+3);
  1595.             *(b+3) = 0;
  1596.             print(b);
  1597.             b += 3;
  1598.         }
  1599.         else {
  1600.             c = *(b+1);
  1601.             *(b+1) = 0;
  1602.             print(b);
  1603.             b++;
  1604.         }
  1605.         *b = c;
  1606.         if(dispmode != DOSV)
  1607.             atrset(0x08 | col);
  1608.         else {
  1609.             c = (col & 15) * 16;
  1610.             atrset(c);
  1611.         }
  1612.         c = *(b+5);
  1613.         *(b+5) = 0;
  1614.         print(b);
  1615.         b += 5;
  1616.         *b = c;
  1617.     }
  1618.     deforutoiro();
  1619.     locate(1,1);
  1620. #endif
  1621. }
  1622.  
  1623. static void pfsetsub(int mode)    /* PFキー表示文字列作成サブ */
  1624. {
  1625. #ifdef FMR
  1626.     char buf[80],*b;
  1627.     struct ATR *at;
  1628.     int i,j,k;
  1629.     unsigned c;
  1630.  
  1631.     switch(mode) {
  1632.     case 0:    b=pfdata;
  1633.             at=pfatr;
  1634.             break;
  1635.     case 1:    b=pfsdata;
  1636.             at=pfsatr;
  1637.             break;
  1638.     case 2:    b=pfcdata;
  1639.             at=pfcatr;
  1640.             break;
  1641.     case 3:    b=pfscdata;
  1642.             at=pfscatr;
  1643.             break;
  1644.     case 4:    b=pfadata;
  1645.             at=pfaatr;
  1646.             break;
  1647.     }
  1648.     for(i=0; i<70; i++){
  1649.         at[i].moji = 0x00;
  1650.         at[i].atr = 0;
  1651.         at[i].color = irotbl[IPFKEY] & 0x07;
  1652.     }
  1653.     switch(mode) {
  1654.     case 0:
  1655.     case 4: sprintf(b,"  "); break;
  1656.     case 1: sprintf(b,"S+"); break;
  1657.     case 3: sprintf(b,"SC"); break;
  1658.     default:sprintf(b,"C+");
  1659.     }
  1660.     for(j = 3,i = 1;i < 11;i++) {
  1661.         if(i == 6) {
  1662.             strcat(b,"  ");
  1663.             j += 2;
  1664.         }
  1665.         pfdispsub(buf,i,mode);
  1666.         for(k=1;k<=5;k++) {
  1667.             at[j+k-1].atr = 0x08;
  1668.             if(iskanji(buf[k])) {
  1669.                 c = *(buf+k)*256 + *(buf+k+1);
  1670.                 c = xjmstojis(c);
  1671.                 *(buf+k) = (char)(c/256);
  1672.                 *(buf+k+1) = (char)(c & 0xff);
  1673.                 at[j+k-1].moji = 0x01;
  1674.                 at[j+k].moji = 0x03;
  1675.                 at[j+k].atr = 0x08;
  1676.                 k++;
  1677.             }
  1678.         }
  1679.         strcat(b,buf);
  1680.         j += 6;
  1681.     }
  1682. #endif
  1683. #ifdef PC_98
  1684.     char buf[80],*b;
  1685.     int i;
  1686.  
  1687.     switch(mode) {
  1688.     case 0: b=pfdata;
  1689.             break;
  1690.     case 1: b=pfsdata;
  1691.             break;
  1692.     case 2: b=pfcdata;
  1693.             break;
  1694.     case 3: b=pfscdata;
  1695.             break;
  1696.     case 4: b=pfadata;
  1697.             break;
  1698.     }
  1699.     switch(mode) {
  1700.     case 0:
  1701.     case 4: sprintf(b,"   "); break;
  1702.     case 1: sprintf(b," S+"); break;
  1703.     case 3: sprintf(b,"SC+"); break;
  1704.     default:sprintf(b," C+");
  1705.     }
  1706.     for(i = 1;i < 11;i++) {
  1707.         if(i == 6) strcat(b,"   ");
  1708.         pfdispsub(buf,i,mode);
  1709.         strcat(b,buf);
  1710.     }
  1711. #endif
  1712. #ifdef PC_AT
  1713.     char buf[80],*b;
  1714.     int i;
  1715.  
  1716.     switch(mode) {
  1717.     case 0: b=pfdata;
  1718.             break;
  1719.     case 1: b=pfsdata;
  1720.             break;
  1721.     case 2: b=pfcdata;
  1722.             break;
  1723.     case 3: b=pfscdata;
  1724.             break;
  1725.     case 4: b=pfadata;
  1726.             break;
  1727.     }
  1728.     switch(mode) {
  1729.     case 0:
  1730.     case 4: sprintf(b,"  "); break;
  1731.     case 1: sprintf(b,"S+"); break;
  1732.     case 3: sprintf(b,"A+"); break;
  1733.     default:sprintf(b,"C+");
  1734.     }
  1735.     for(i = 1;i < 13;i++) {
  1736.         if(i == 5 || i == 9) strcat(b,"  ");
  1737.         pfdispsub(buf,i,mode);
  1738.         strcat(b,buf);
  1739.     }
  1740. #endif
  1741. }
  1742.  
  1743. void pfset(void)        /* PFキー表示文字列作成 */
  1744. {
  1745.     pfsetsub(0);
  1746.     pfsetsub(1);
  1747.     pfsetsub(2);
  1748.     pfsetsub(3);
  1749.     pfsetsub(4);
  1750. }
  1751.  
  1752. void stsdisp(void)        /* モード別状態表示 */
  1753. {
  1754.     char buf[39];
  1755.  
  1756.     if(erron) return;
  1757.     memset(buf,0,39);
  1758.     switch(nifmode) {
  1759.     case NFID:
  1760.         iro(IID);
  1761.         sprintf(&buf[1],"ID:%s",nifid);
  1762.         break;
  1763.     case NFSEARCH:
  1764.         iro(IKEN);
  1765.         sprintf(&buf[1],"検索文字:%d件",kensakukensu);
  1766.         break;
  1767.     case NFAUTO1:
  1768.         iro(ISETUMEI);
  1769.         sprintf(&buf[1]," 自動表示 (改行キー:中止 空白キー:停止) ");
  1770.         break;
  1771.     case NFAUTO2:
  1772.         iro(ISETUMEI);
  1773.         sprintf(&buf[1]," 表示停止 (改行キー:中止 空白キー:再開) ");
  1774.         break;
  1775.     case NFCOMENT:
  1776.     case NFCOMENTID:
  1777.         if(gpo->mode == NFORUM || gpo->mode == NSEPA) {
  1778.             iro(ICMT);
  1779.             tbl_set(gpo);
  1780.             if(gpo->flag & FCYCLE) {
  1781.                 if(!gpo->p->cid)
  1782.                     sprintf(&buf[1],"           コメント数:%d",
  1783.                      gpo->p->cno);
  1784.                 else
  1785.                     sprintf(&buf[1]," %05uへのコメント コメント数:%d",
  1786.                      gpo->p->cid,gpo->p->cno);
  1787.             }
  1788.             else {
  1789.                 if(!gpo->p->cid)
  1790.                     sprintf(&buf[1],"         コメント数:%d",
  1791.                      gpo->p->cno);
  1792.                 else
  1793.                     sprintf(&buf[1]," %03dへのコメント コメント数:%d",
  1794.                      gpo->p->cid,gpo->p->cno);
  1795.             }
  1796.             break;
  1797.         }
  1798.     default:
  1799.         iro(ISETUMEI);
  1800.         sprintf(&buf[1]," 通常 (ESCキー:終了・復帰 空白キー:選択) ");
  1801.         break;
  1802.     }
  1803.     loc(1,line-1);
  1804.     switch(nextmode) {
  1805.     case 0: buf[0] = ' ';break;
  1806.     case 1: buf[0] = '-';break;
  1807.     default: buf[0] = '*';break;
  1808.     }
  1809.     strncat(buf,space,38-strlen(buf));
  1810.     print(buf);
  1811.     deforutoiro();
  1812. }
  1813.  
  1814. char keyget2(int mode)    /* キー入力 */
  1815. {
  1816.     int savea=0,a,b,c;
  1817.     int saveaa=0,saveaaa=0;
  1818.     while(1) {
  1819. #ifdef FMR
  1820.         regs.h.ah = 0x08;
  1821.         xint90();
  1822.         a = (int)((regs.h.al >> 2) & 0x07);
  1823.         switch(a) {
  1824.         case 0:
  1825.         case 1: break;
  1826.         case 4: a = 2; break;
  1827.         default: a = 3; break;
  1828.         }
  1829. #endif
  1830. #ifdef PC_98
  1831.         regs.h.ah = 0x02;
  1832.         xint86(0x18);
  1833.         a = (int)(regs.h.al & 0x06);
  1834.         if(a != saveshift) {
  1835.             saveshift = a;
  1836.             loc(77,line);
  1837.             atrset(6);
  1838.             switch(a) {
  1839.             case 2: print("CAPS");break;
  1840.             case 4:
  1841.             case 6: print(" カナ ");break;
  1842.             default: print("    ");break;
  1843.             }
  1844.             deforutoiro();
  1845.         }
  1846.         a = (int)(regs.h.al & 0x11);
  1847.         switch(a) {
  1848.         case 0:
  1849.         case 1: break;
  1850.         case 0x10: a = 2; break;
  1851.         default: a = 3; break;
  1852.         }
  1853. #endif
  1854. #ifdef PC_AT
  1855.         regs.h.ah = 0x02;
  1856.         xint86(0x16);
  1857.         a = (int)(regs.h.al & 0x0f);
  1858.         switch(a) {
  1859.         case 0: break;
  1860.         case 1:
  1861.         case 2:
  1862.         case 3: a = 1; break;
  1863.         case 4: a = 2; break;
  1864.         default: a = 3; break;
  1865.         }
  1866. #endif
  1867.         if(keyshiftmode) {
  1868.             if(a && a != saveaaa) {
  1869.                 saveaa++;
  1870.                 if(saveaa > 3) saveaa = 0;
  1871.             }
  1872.             saveaaa = a;
  1873.             a = saveaa;
  1874.         }
  1875.         if(savea != a) {
  1876.             if(nifmode == NFAUTO1) pfdisp(4);
  1877.             else                   pfdisp(a);
  1878.             savea = a;
  1879.         }
  1880.         jikokudisp(1,mode);
  1881.         if(mode == 2 && autodispsw) {
  1882.             autodispsw=0;
  1883.             return((char)0);
  1884.         }
  1885.         if(savea != 3) c = savea * 0x20;
  1886.         else           c = 0;
  1887.         if(!keycheck()) {
  1888.             xint86(0x28);    /* INT 28 CALL */
  1889.             continue;
  1890.         }
  1891.         sv_time[0] = lsavetime[0];
  1892. #ifdef FMR
  1893.         regs.x.ax = 0x0900;
  1894.         xint90();            /* キー入力 */
  1895.         a = (int)regs.h.bh;
  1896.         b = (int)regs.h.dl;
  1897.         if(b == 0xff) {
  1898.             regs.x.ax = 0x0900;
  1899.             xint90();        /* キー入力 */
  1900.             b = (int)regs.h.dl;
  1901.             if(b >= '1' && b <= ':') {
  1902.                 if(savea != 3) b = b + 0x81 - '1' + c;
  1903.                 else           b = b + 0xf5 - '1';
  1904.                 break;
  1905.             }
  1906.             if(b >= ';' && b <= '?') {
  1907.                 b = b + 0x81 - '1' + c;
  1908.                 break;
  1909.             }
  1910.             if(b >= '@' && b <= 'D') {
  1911.                 b = b + 0xe0 - '@';
  1912.                  b += savea * 8;
  1913.                 break;
  1914.             }
  1915.             if(b >= 'E' && b <= 'F') {
  1916.                 b = b + 0x94 - 'E' + c;
  1917.                 break;
  1918.             }
  1919.             continue;
  1920.         }
  1921.         if(b == 0x81) {        /* オアシスのシフト+0 */
  1922.             b = 0xaa;
  1923.             break;
  1924.         }
  1925.         if(a >= 2 && a <= 11) {    /* 数字キー→PFキー変換処理 */
  1926.             if(savea != 3) b = a + 0x81-2 + c;
  1927.             else           b = a + 0xf5-2;
  1928.             break;
  1929.         }
  1930.         if(a == 0x72) {        /* 取消キー */
  1931.             b = 0x9b + c;
  1932.             break;
  1933.         }
  1934.         if(a == 0x73) {        /* 実行キー */
  1935.             b = 0x9a + c;
  1936.             break;
  1937.         }
  1938.         if(b == 0x0d){
  1939.             switch(savea) {
  1940.             case 1: b = 0xa0; break;
  1941.             case 2: b = 0xc0;
  1942.             }
  1943.             break;
  1944.         }
  1945.         if(a == 0x48) {        /* 挿入キー */
  1946.             b = 0x98 + c;
  1947.             break;
  1948.         }
  1949.         if(a == 0x4b) {        /* 削除キー */
  1950.             if(regs.h.dh == 0x80) b = 0x97;    /* オアシス ? --> センタリングキー */
  1951.             else                  b = 0x99;
  1952.             b += c;
  1953.             break;
  1954.         }
  1955.         if(regs.h.dh == 0x80) {    /* PFキー,編集キー */
  1956.             switch(a) {
  1957.             case 0x29:        /* オアシス改頁キー */
  1958.                         b = 0x9f;
  1959.                         break;
  1960.             case 0x4e:        /* オアシス文末キー */
  1961.                         b = 0x96;
  1962.                         break;
  1963.             case 0x6b:
  1964.             case 0x6c:
  1965.             case 0x6d:        /* オアシス前頁,頁指定,次頁キー */
  1966.                         b = a + 0x9c - 0x6b;
  1967.                         break;
  1968.             case 0x6e:        /* 前行キー */
  1969.                         b = 0x94;
  1970.                         break;
  1971.             case 0x70:        /* 次行キー */
  1972.                         b = 0x95;
  1973.                         break;
  1974.             case 0x71:        /* オアシス削除キー */
  1975.                         b = 0x99;
  1976.                         break;
  1977.             default:    break;    /* その他のキー */
  1978.             }
  1979.             b += c;
  1980.             break;
  1981.         }
  1982.         else if(b >= 128) continue;
  1983.         switch(b) {
  1984.         case 0x0b:                    /* HOMEキー */
  1985.         case 0x0c: b = 0x96;break;    /* CLSキー */
  1986.         case 0x1c: b = 0x93;break;    /* →キー */
  1987.         case 0x1d: b = 0x92;break;    /* ←キー */
  1988.         case 0x1e: b = 0x90;break;    /* ↑キー */
  1989.         case 0x1f: b = 0x91;break;    /* ↓ー */
  1990.         default:   break;            /* その他のキー */
  1991.         }
  1992.         if(b >= 128) b += c;
  1993.         else {
  1994.             if(b >= '0' && b <= '9') {
  1995.                 if(b == '0') b = 10;
  1996.                 else         b = b - '0';
  1997.                 if(savea != 3) b = b + 0x80 + c;
  1998.                 else           b = b + 0xf4;
  1999.                 break;
  2000.             }
  2001.         }
  2002.         break;
  2003. #endif
  2004. #ifdef PC_98
  2005.         regs.h.ah = 0x00;
  2006.         xint86(0x18);            /* キー入力 */
  2007.         a = (int)regs.h.ah;
  2008.         b = (int)regs.h.al;
  2009.         if(a >= 1 && a <= 10) {    /* 数字キー→PFキー変換処理 */
  2010.             if(savea != 3) b = a + 0x80 + c;
  2011.             else           b = a + 0xf4;
  2012.             break;
  2013.         }
  2014.         if(b == 0x0d) {
  2015.             switch(savea) {
  2016.             case 1: b = 0xa0; break;
  2017.             case 2: b = 0xc0;
  2018.             }
  2019.             break;
  2020.         }
  2021.         if(b) {
  2022.             if(b >= 128) continue;
  2023.             if(b >= '0' && b <= '9') {
  2024.                 if(b == '0') b = 10;
  2025.                 else         b = b - '0';
  2026.                 if(savea != 3) b = b + 0x80 + c;
  2027.                 else           b = b + 0xf4;
  2028.                 break;
  2029.             }
  2030. /*            b += c; */
  2031.             break;
  2032.         }
  2033.         if(a >= 0x62 && a <= 0x6b) {    /* PF1~10キー */
  2034.             if(savea != 3) b = a + 0x81-0x62 + c;
  2035.             else           b = a + 0xf5-0x62;
  2036.             break;
  2037.         }
  2038.         if(a >= 0x82 && a <= 0x8b) {    /* シフト+PF1~10キー */
  2039.             if(savea != 3) b = a + 0xa1-0x82;
  2040.             else           b = a + 0xf5-0x82;
  2041.             break;
  2042.         }
  2043.         if(a >= 0x92 && a <= 0x9b) {    /* CTL+PF1~10キー */
  2044.             if(savea != 3) b = a + 0xc1-0x92;
  2045.             else           b = a + 0xf5-0x92;
  2046.             break;
  2047.         }
  2048.         if(a >= 0x52 && a <= 0x56) {    /* PF11~15キー */
  2049.             b = a + 0x8b-0x52 + c;
  2050.             break;
  2051.         }
  2052.         if(a >= 0xc2 && a <= 0xc6) {    /* シフト+PF11~15キー */
  2053.             b = a + 0xab-0xc2;
  2054.             break;
  2055.         }
  2056.         if(a >= 0xd2 && a <= 0xd6) {    /* CTL+PF11~15キー */
  2057.             b = a + 0xcb-0xd2;
  2058.             break;
  2059.         }
  2060.         if(a == 0xae) {            /* CLRキー */
  2061.             b = 0xb6;
  2062.             break;
  2063.         }
  2064.         switch(a) {                /* ROLLUP,ROLLDOWN,INS,DEL,↑,← */
  2065.                                 /* ,→,↓,HOME,HELPキー */
  2066.         case 0x36: b = 0x94; break;
  2067.         case 0x37: b = 0x95; break;
  2068.         case 0x38: b = 0x98; break;
  2069.         case 0x39: b = 0x99; break;
  2070.         case 0x3a: b = 0x90; break;
  2071.         case 0x3b: b = 0x92; break;
  2072.         case 0x3c: b = 0x93; break;
  2073.         case 0x3d: b = 0x91; break;
  2074.         case 0x3e: b = 0x96; break;
  2075.         case 0x3f: b = 0x97; break;
  2076.         }
  2077.         b += c;
  2078.         break;
  2079. #endif
  2080. #ifdef PC_AT
  2081.         if(dispmode) regs.h.ah = 0x10;
  2082.         else         regs.h.ah = 0x00;
  2083.         xint86(0x16);                    /* キー入力 */
  2084.         a = (int)regs.h.ah;
  2085.         b = (int)regs.h.al;
  2086.         if(b == 0xe0) b = 0;
  2087.  
  2088.         if(b && b >= 128) continue;
  2089.         if(a >= 0x02 && a <= 0x0b) {    /* 数字キー */
  2090.             if(savea != 3) b = a + 0x81 - 0x02 + c;
  2091.             else           b = a + 0xf5-0x02;
  2092.             break;
  2093.         }
  2094.         if(a >= 0x3b && a <= 0x44) {    /* F1~F10キー */
  2095.             if(savea != 3) b = a + 0x81 - 0x3b + c;
  2096.             else           b = a + 0xf5-0x3b;
  2097.             break;
  2098.         }
  2099.         if(a >= 0x54 && a <= 0x5d) {    /* シフト+F1~F10キー */
  2100.             if(savea != 3) b = a + 0xa1 - 0x54;
  2101.             else           b = a + 0xf5-0x54;
  2102.             break;
  2103.         }
  2104.         if(a >= 0x5e && a <= 0x67) {    /* CNTL+F1~F10キー */
  2105.             if(savea != 3) b = a + 0xc1 - 0x5E;
  2106.             else           b = a + 0xf5-0x5e;
  2107.             break;
  2108.         }
  2109.         if(a >= 0x68 && a <= 0x71) {    /* ALT+F1~F10キー */
  2110.             b = a + 0xf5 - 0x68;
  2111.             break;
  2112.         }
  2113.         switch(a) {
  2114.         case 0x48:
  2115.         case 0X8d:    b = 0x90;break;    /* ↑キー */
  2116.         case 0x4b:
  2117.         case 0x73:    b = 0x92;break;    /* ←キー */
  2118.         case 0x4d:
  2119.         case 0x74:    b = 0x93;break;    /* →キー */
  2120.         case 0x50:
  2121.         case 0x91:    b = 0x91;break;    /* ↓キー */
  2122.         case 0x1c:    if(!c) b = 0x0d;
  2123.                     else b = 0x80;break;    /* ENTERキー */
  2124.         case 0x39:    b = 0x20;break;    /* 空白キー */
  2125.         case 0x49:
  2126.         case 0x84:    b = 0x94;break;    /* PAGEUPキー */
  2127.         case 0x51:
  2128.         case 0x76:    b = 0x95;break;    /* PAGEDWNキー */
  2129.         case 0x52:
  2130.         case 0x92:    b = 0x98;break;    /* INSキー */
  2131.         case 0x53:
  2132.         case 0x93:    b = 0x99;break;    /* DELキー */
  2133.         case 0x47:
  2134.         case 0x77:    b = 0x96;break;    /* HOMEキー */
  2135.         case 0x4f:
  2136.         case 0x75:    b = 0x9a;break;    /* ENDキー */
  2137.         case 0x85:
  2138.         case 0x87:
  2139.         case 0x89:    b = 0x8b;break;    /* PF11キー */
  2140.         case 0x86:
  2141.         case 0x88:
  2142.         case 0x8a:    b = 0x8c;break;    /* PF12キー */
  2143.         }
  2144.         if(b >= 128)
  2145.             b += c;
  2146.         break;
  2147. #endif
  2148.     }
  2149.     if(savea) pfdisp(0);
  2150.     if(erron) {
  2151.         erron = 0;
  2152.         stsdisp();                /* エラー表示クリア */
  2153.     }
  2154.     regs.x.ax = 0x0cff;
  2155.     xintdos();
  2156.  
  2157.     return((char)b);
  2158. }
  2159.  
  2160. static int cnv_env(char *s)
  2161. {
  2162.     int i,j;
  2163.     char buf[81],work[81],*o,*p;
  2164.  
  2165.     for(i=j=0;j < 81 && s[i];i++) {
  2166.         if(iskanji(s[i]) && iskanji2(s[i+1])) {
  2167.             buf[j++] = s[i++];
  2168.             buf[j++] = s[i];
  2169.             continue;
  2170.         }
  2171.         if(s[i] == '%') {
  2172.             o = &s[i+1];
  2173.             if(p = jstrchr(o,'%')) {
  2174.                 *p++ = 0;
  2175.                 strcpy(work,o);
  2176.                 strupr(work);
  2177.                 i += strlen(o) + 1;
  2178.                 if(o = getenv(work)) {
  2179.                     strcpy(&buf[j],o);
  2180.                     j += strlen(o);
  2181.                 }
  2182.                 continue;
  2183.             }
  2184.         }
  2185.         buf[j++] = s[i];
  2186.     }
  2187.     buf[j] = 0;
  2188.     strcpy(s,buf);
  2189.     return(strlen(s));
  2190. }
  2191.  
  2192. void cgetsx(char *s,int mode)    /* デフォルト付き文字列入力 */
  2193. {
  2194.     int i;
  2195.     int a;
  2196.  
  2197.     regs.x.ax = 0x0cff;
  2198.     xintdos();
  2199.  
  2200.     cnv_env(&s[2]);
  2201.     s[1] = strlen(&s[2]);
  2202.     printf("%s",&s[2]);
  2203.     cslon();
  2204.     for(i = s[1];(a = (int)getch()) != '\r';) {
  2205. #ifdef FMR
  2206.         if(a == 0x1e) a = 0x0b;
  2207.         else if(a == 0x1d) a = '\b';
  2208. #endif
  2209. #ifdef PC_AT
  2210.         if(a == 0) {
  2211.             a = (int)getch();
  2212.             if(a == 0x48) a = 0x0b;
  2213.             else if(a == 0x4b) a = '\b';
  2214.             else continue;
  2215.         }
  2216. #endif
  2217.         if(a == 0xff) {
  2218.             getch();
  2219.             continue;
  2220.         }
  2221.         if(a == 0x18 || a == 0x0b) {
  2222.             if(!mode) {
  2223.                 for(;i;i--) {
  2224.                     putchar('\b');
  2225.                     putchar(' ');
  2226.                     putchar('\b');
  2227.                 }
  2228.             }
  2229.             else {
  2230.                 if(!i) continue;
  2231.                 if((nthctype(&s[2],i-1) == CT_ANK)
  2232.                  && (s[2+i-1] == ':' || s[2+i-1] == '\\')) {
  2233.                     i--;
  2234.                     putchar('\b');
  2235.                     putchar(' ');
  2236.                     putchar('\b');
  2237.                 }
  2238.                 for(;i;) {
  2239.                     if(nthctype(&s[2],i-1) != CT_ANK) {
  2240.                         i -= 2;
  2241.                         putchar('\b');
  2242.                         putchar(' ');
  2243.                         putchar('\b');
  2244.                         putchar('\b');
  2245.                         putchar(' ');
  2246.                         putchar('\b');
  2247.                     }
  2248.                     else {
  2249.                         if(s[2+i-1] != ':' && s[2+i-1] != '\\') {
  2250.                             i--;
  2251.                             putchar('\b');
  2252.                             putchar(' ');
  2253.                             putchar('\b');
  2254.                         }
  2255.                         else break;
  2256.                     }
  2257.                 }
  2258.             }
  2259.             continue;
  2260.         }
  2261.         if(a == '\r') break;
  2262.         if(a == '\b') {
  2263.             if(!i) continue;
  2264.             i--;
  2265.             if(nthctype(&s[2],i) == CT_KJ2) {
  2266.                 i--;
  2267.                 putchar((char)a);
  2268.                 putchar(' ');
  2269.                 putchar((char)a);
  2270.             }
  2271.             putchar((char)a);
  2272.             putchar(' ');
  2273.             putchar((char)a);
  2274.             continue;
  2275.         }
  2276.         if(a == '\t')
  2277.             a = ' ';
  2278.         if(a == 0x1b) {
  2279.             s[2] = (char)a;
  2280.             i = 1;
  2281.             break;
  2282.         }
  2283.         if(a < ' ' || a == 0x7f) continue;
  2284.         if(iskanji(a) && i >= s[0]-1) {
  2285.             getch();
  2286.             continue;
  2287.         }
  2288.         if(i >= s[0]) continue;
  2289.         putchar((char)a);
  2290.         s[2+i++] = (char)a;
  2291.     }
  2292.     csloff();
  2293.     s[2+i] = 0;
  2294.     s[1] = cnv_env(&s[2]);
  2295. }
  2296.  
  2297. int rtncut(char *a)        /* 文字列から改行カット */
  2298. {
  2299.     char c;
  2300.     int i,j;
  2301.  
  2302.     for(i = 0,j = 0;(c = a[i]);i++) {
  2303.         if(c == '\n' || c == '\r')    {
  2304.             a[j] = 0;
  2305.             return(1);
  2306.         }
  2307.         if(c == '\b') {
  2308.             if(j) {
  2309.                 j--;
  2310.                 continue;
  2311.             }
  2312.         }
  2313.         if(c < ' ') a[j++] = ' ';
  2314.         else        a[j++] = c;
  2315.     }
  2316.     a[j] = 0;
  2317.     return(0);
  2318. }
  2319.  
  2320. void rtncut2(char *a)        /* 文字列からBSカット */
  2321. {
  2322.     char c;
  2323.     int i,j;
  2324.  
  2325.     for(i = 0,j = 0;(c = a[i]);i++) {
  2326.         if(c == '\b') {
  2327.             if(j) {
  2328.                 j--;
  2329.                 continue;
  2330.             }
  2331.         }
  2332.         a[j++] = c;
  2333.     }
  2334.     a[j] = 0;
  2335. }
  2336.  
  2337. int yesnocheck(char *s)        /* yes/noチェック */
  2338. {
  2339.     char a,buf[81];
  2340.     int i;
  2341.  
  2342.     xlocate();
  2343.     sprintf(buf,"%s(Y/N) ",s);
  2344.     kprintf(buf);
  2345.     regs.x.ax = 0x0cff;
  2346.     xintdos();
  2347.     cslon();
  2348.     for(;a = getch();) {
  2349.         if(a == 0xff) {
  2350.             getch();
  2351.             continue;
  2352.         }
  2353.         if(a == 0x1b) {
  2354.             i = 0;
  2355.             break;
  2356.         }
  2357.         if(a == 'n' || a == 'N') {
  2358.             i = 0;
  2359.             break;
  2360.         }
  2361.         if(a == 'y' || a == 'Y') {
  2362.             i = 1;
  2363.             break;
  2364.         }
  2365.         if(a == '\r') {
  2366.             i = yesnomode;
  2367.             break;
  2368.         }
  2369.     }
  2370.     csloff();
  2371.     return(i);
  2372. }
  2373.  
  2374. static void errdisp(char *s,int mode)    /* エラーメッセージ表示サブ */
  2375. {
  2376.     char buf[81],c;
  2377.  
  2378.     if(erron == 2) {
  2379.         printf("%s\n",s);
  2380.         return;
  2381.     }
  2382.     if(erron) return;
  2383.     erron = 1;
  2384.     xlocate();
  2385.     xxstrncpy80(buf,s);
  2386.     if(mode) strncat80(buf," : 何かキーを押してください。");
  2387.     strncat80(buf,space);
  2388. #ifndef PC_AT
  2389.     atrset(irotbl[IERROR] + 8);
  2390. #else
  2391.     if(dispmode == DOSV) {
  2392.         c = (irotbl[IERROR] & 15) * 16;
  2393.         c += irotbl[IERROR] / 16;
  2394.         atrset(c);
  2395.     }
  2396.     else {
  2397.         atrset(irotbl[IERROR] + 8);
  2398.     }
  2399. #endif
  2400.     print(buf);
  2401.     deforutoiro();
  2402.     if(mode) {
  2403.         keyget();
  2404.         erron = 0;
  2405.     }
  2406. }
  2407.  
  2408. void errdisp1(char *s)        /* エラーメッセージ表示(1) */
  2409. {
  2410.     errdisp(s,0);
  2411. }
  2412.  
  2413. void errdisp2(char *s)        /* エラーメッセージ表示(2) */
  2414. {
  2415.     errdisp(s,1);
  2416. }
  2417.  
  2418. void errdisp3(char *s)        /* エラーメッセージ表示(3) メモリ不足時のみ */
  2419. {
  2420.     foutmode |= F_MEMERR;
  2421.     errdisp(s,1);
  2422. }
  2423.  
  2424. void kprintf(char *buf)        /* 確認メッセージ表示 */
  2425. {
  2426.     erron = 0;
  2427.     iro(IKAKUNIN);
  2428.     print(buf);
  2429.     deforutoiro();
  2430.     locate(keta,gyo);
  2431. }
  2432.  
  2433. void eprintf(char *buf)        /* エラーメッセージ表示 */
  2434. {
  2435.     iro(IERROR);
  2436.     print(buf);
  2437.     deforutoiro();
  2438. }
  2439.  
  2440. void nstatus(int mode,PCELL far *po,int tno,int maxtno,int lno,int maxlno)
  2441. {                /* ライン数など状態表示 */
  2442.     char buf[81];
  2443.     PCELL far *l;
  2444.  
  2445.     tbl_set(po);
  2446.     if(fno != po->p->fno) {
  2447.         fno = po->p->fno;
  2448.         topdisp();
  2449.     }
  2450.     l = po->grp;
  2451.     if(savepno == -1 || savepno != l->count || savepflag != po->flag) {
  2452.         loc(1,2);
  2453.         memset(buf,0,81);
  2454.         sprintf(buf,"- ");
  2455.         tbl_set(l);
  2456.         _fstrncpy((char far *)&buf[2],l->p->title,78);
  2457.         if(strlen(buf) == 80 && nthctype(buf,79) == CT_KJ1) {
  2458.             buf[79] = 0;
  2459.         }
  2460.         switch(po->flag & ~(FTAG+FYOMI+FCYCLE)) {
  2461.         case FSENTAKU: iro(IRSENTAKU);
  2462.                        buf[1] = '+';
  2463.                        break;
  2464.         case FSAKUJYO: iro(IRSAKUJYO);
  2465.                        buf[1] = 'd';
  2466.                        break;
  2467.         case FSENTAKU+FSAKUJYO: iro(IRGATTAI);
  2468.                        buf[1] = '*';
  2469.                        break;
  2470.         default:       if(po->flag & FYOMI) {
  2471.                             iro(IRYOMI);
  2472.                             buf[1] = '-';
  2473.                        }
  2474.                        else iro(IMODE);
  2475.                        break;
  2476.         }
  2477.         strncat80(buf,space);
  2478.         print(buf);
  2479.         savepno = l->count;
  2480.         savepflag = po->flag;
  2481.     }
  2482.     gpo = po;
  2483.     if(erron) return;
  2484.     stsdisp();
  2485.     loc(39,line-1);iro(ILINE);
  2486.     if(tno == maxtno) tno--;
  2487.     sprintf(buf," %3d/%3dファイル %4d/%4dタイトル ",fno,maxfno,tno,maxtno-1);
  2488.     print(buf);
  2489.     loc(66,line-1);
  2490.     if(mode) {
  2491.         sprintf(buf,"%3d/%3dライン ",lno,maxlno);
  2492.         print(buf);
  2493.         loc(77,line-1);
  2494.         if(lno <= line-4) { iro(ILINE); print(" "); }
  2495.         else { iro(IUP);print("↑"); }
  2496.         loc(79,line-1);
  2497.         if(lno >= maxlno) { iro(ILINE); print(" "); }
  2498.         else { iro(IDOWN);print("↓"); }
  2499.     }
  2500.     else {
  2501.         print(" ----- ライン ");
  2502.         loc(77,line-1);
  2503.         if(lno <= line-4)    { iro(ILINE); print(" "); }
  2504.         else            { iro(IUP);print("↑"); }
  2505.         loc(79,line-1);
  2506.         if(lno >= maxtno)    { iro(ILINE); print(" "); }
  2507.         else            { iro(IDOWN);print("↓"); }
  2508.     }
  2509.     deforutoiro();
  2510. }
  2511.  
  2512. void xnstatus(void)            /* 処理タイトル数表示 */
  2513. {
  2514.     char buf[81];
  2515.  
  2516.     if(erron) return;
  2517.     loc(39+18,line-1);iro(ILINE);
  2518.     sprintf(buf,"%4d",p-1);
  2519.     print(buf);
  2520.     deforutoiro();
  2521. }
  2522.  
  2523. void topdisp(void)            /* トップタイトル表示 */
  2524. {
  2525.     char *a,buf[81];
  2526.  
  2527.     if(maxfno > 1)
  2528.         _fstrcpy((char far *)filename,file[fno-1]);
  2529.     if(!(a = jstrrchr(filename,'\\')) && !(a = jstrrchr(filename,':')))
  2530.         a = filename;
  2531.     else    a++;
  2532.     if(strlen(a) > 12) a = "";
  2533.     loc(1,1);iro(IFILE);
  2534.     sprintf(buf,"%s",a);
  2535.     strcpy(gfilename,a);
  2536.     strncat(buf,space,12-strlen(buf));
  2537.     print(buf);
  2538.     loc(13,1);iro(INIFMODE);
  2539.     switch(nifmode) {
  2540.     case NFCOMENT: sprintf(buf," コメント ");break;
  2541.     case NFCOMENTID: sprintf(buf,"コメントID");break;
  2542.     case NFSEARCH: sprintf(buf," 検索 ");break;
  2543.     case NFID    : sprintf(buf," ID ");break;
  2544.     default:       sprintf(buf," ノーマル ");break;
  2545.     }
  2546.     print(buf);
  2547.     loc(19,1);iro(ITITLE);
  2548.     print("  NIFP(Ver 3.71) ログページャ by やなさん:GHC00073 ");
  2549.     jikokudisp(0,0);
  2550. }
  2551.     
  2552. int asctodec(char *buf)        /* アスキー文字から数字へ変換 */
  2553. {
  2554.     int i;
  2555.  
  2556.     i = (buf[0]-'0') * 100;
  2557.     i += (buf[1]-'0') * 10;
  2558.     i += (buf[2]-'0');
  2559.     if(buf[3] >= '0' && buf[3] <= '9') {
  2560.         i *= 100;
  2561.         i += (buf[3]-'0') * 10;
  2562.         i += (buf[4]-'0');
  2563.     }
  2564.     return(i);
  2565. }
  2566.  
  2567. char jiskatatbl[] = { 0x00,0xa7,0x00,0xb1,0x00,0xa8,0x00,0xb2,
  2568.                       0x00,0xa9,0x00,0xb3,0x00,0xaa,0x00,0xb4,
  2569.                       0x00,0xab,0x00,0xb5,0x00,0xb6,0xde,0xb6,
  2570.                       0x00,0xb7,0xde,0xb7,0x00,0xb8,0xde,0xb8,
  2571.                       0x00,0xb9,0xde,0xb9,0x00,0xba,0xde,0xba,
  2572.                       0x00,0xbb,0xde,0xbb,0x00,0xbc,0xde,0xbc,
  2573.                       0x00,0xbd,0xde,0xbd,0x00,0xbe,0xde,0xbe,
  2574.                       0x00,0xbf,0xde,0xbf,0x00,0xc0,0xde,0xc0,
  2575.                       0x00,0xc1,0xde,0xc1,0x00,0xaf,0x00,0xc2,
  2576.                       0xde,0xc2,0x00,0xc3,0xde,0xc3,0x00,0xc4,
  2577.                       0xde,0xc4,0x00,0xc5,0x00,0xc6,0x00,0xc7,
  2578.                       0x00,0xc8,0x00,0xc9,0x00,0xca,0xde,0xca,
  2579.                       0xdf,0xca,0x00,0xcb,0xde,0xcb,0xdf,0xcb,
  2580.                       0x00,0xcc,0xde,0xcc,0xdf,0xcc,0x00,0xcd,
  2581.                       0xde,0xcd,0xdf,0xcd,0x00,0xce,0xde,0xce,
  2582.                       0xdf,0xce,0x00,0xcf,0x00,0xd0,0x00,0x00,
  2583.                       0x00,0xd1,0x00,0xd2,0x00,0xd3,0x00,0xac,
  2584.                       0x00,0xd4,0x00,0xad,0x00,0xd5,0x00,0xae,
  2585.                       0x00,0xd6,0x00,0xd7,0x00,0xd8,0x00,0xd9,
  2586.                       0x00,0xda,0x00,0xdb,0x00,0x00,0x00,0xdc,
  2587.                       0x00,0x00,0x00,0x00,0x00,0xa6,0x00,0xdd,
  2588.                       0xde,0xb3,0x00,0x00,0x00,0x00 };
  2589. static unsigned cnvkata1(unsigned w)
  2590. {
  2591.     if(w == 0x815b) return(0xb0);
  2592.     w -= 0x8340;
  2593.     w *= 2;
  2594.     if(jiskatatbl[w])
  2595.         return(jiskatatbl[w+1]*256 | jiskatatbl[w]);
  2596.     return((unsigned)jiskatatbl[w+1]);
  2597. }
  2598.  
  2599. char asckatatbl[] = { 0x92,0x40,0x42,0x44,0x46,0x48,0x83,0x85,
  2600.                       0x87,0x62,0x00,0x41,0x43,0x45,0x47,0x49,
  2601.                       0x4a,0x4c,0x4e,0x50,0x52,0x54,0x56,0x58,
  2602.                       0x5a,0x5c,0x5e,0x60,0x63,0x65,0x67,0x69,
  2603.                       0x6a,0x6b,0x6c,0x6d,0x6e,0x71,0x74,0x77,
  2604.                       0x7a,0x7d,0x7e,0x80,0x81,0x82,0x84,0x86,
  2605.                       0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8f,0x93 };
  2606. static unsigned cnvkata2(unsigned w,char c)
  2607. {
  2608.     unsigned d;
  2609.  
  2610.     if(w == 0xb0) return(0x815b);
  2611.     d = (unsigned)asckatatbl[w - 0xa6];
  2612.     if(c == '゙') d++;
  2613.     else if(c == '゚') d += 2;
  2614.     return(0x8300 | d);
  2615. }
  2616.  
  2617. int rtnk=0;
  2618. char *substrstr(char *b1,char *b2)    /* 文字列検索 */
  2619. {
  2620.     char c;
  2621.     unsigned w,x,y;
  2622.     int i,j,k,l1,l2;
  2623.  
  2624.     l2 = strlen(b2);
  2625.     l1 = strlen(b1);
  2626.     if(l1 < l2) return((char *)NULL);
  2627.     l1 -= l2;
  2628.     for(i = 0;i <= l1;i++) {
  2629.         for(k = i,j = 0;j < l2;j++,k++) {
  2630.             x = (unsigned)(b1[k]*256 + b1[k+1]);
  2631.             if(iskanji(b2[j])) {    /* 全角? */
  2632.                 w = (unsigned)(b2[j]*256 + b2[j+1]);
  2633.                 j++;
  2634.                 y = w;
  2635.                 if(jishira(w)) {    /* ひらがな? */
  2636.                     y = jtokata(w);
  2637.                     goto chkxx;
  2638.                 }
  2639.                 if(jiskata(w)) {    /* カタカナ? */
  2640.                     y = jtohira(w);
  2641.                     goto chkxx;
  2642.                 }
  2643.                 if(jisupper(w)) {    /* 英大文字? */
  2644.                     y = jtolower(w);
  2645.                     goto chkxx;
  2646.                 }
  2647.                 if(jislower(w)) {    /* 英小文字? */
  2648.                     y = jtoupper(w);
  2649.                 }
  2650. chkxx:
  2651.                 if(x == w || x == y) {
  2652.                     k++;
  2653.                     continue;
  2654.                 }
  2655.                 if(w >= 0x839e) break;
  2656.                 if(jiskata(w)) {
  2657.                     w=cnvkata1(w);
  2658.                     y = w;
  2659.                 }
  2660.                 else if(jiskata(y)) {
  2661.                     w=cnvkata1(y);
  2662.                     y = w;
  2663.                 }
  2664.                 else {
  2665.                     w=zentohan(w);
  2666.                     y = zentohan(y);
  2667.                 }
  2668.                 if(w >= 256) {
  2669.                     if(x == w) {
  2670.                         k++;
  2671.                         continue;
  2672.                     }
  2673.                 }
  2674.                 else
  2675.                     if(b1[k] == (char)w || b1[k] == (char)y)
  2676.                             continue;
  2677.             }
  2678.             else {
  2679.                 w = (unsigned)b2[j];
  2680.                 y = w;
  2681.                 if(w >= 'A' && w <= 'Z') y = (w + 'a' - 'A');
  2682.                 else if(w >= 'a' && w <= 'z') y = (w - 'a' + 'A');
  2683.                 if(b1[k] == w || b1[k] == y) continue;
  2684.                 if(iskmoji(w)) {
  2685.                     if(b2[j+1] == '゚') c = '゚';
  2686.                     else if(b2[j+1] == '゙') c = '゙';
  2687.                     else c = 0;
  2688.                     y = cnvkata2(w,c);
  2689.                     w = jtohira(y);
  2690.                     if(c) j++;
  2691.                 }
  2692.                 else {
  2693.                     w = hantozen(w);
  2694.                     y = hantozen(y);
  2695.                 }
  2696.                 if(x == y || x == w) {
  2697.                     k++;
  2698.                     continue;
  2699.                 }
  2700.             }
  2701.             break;
  2702.         }
  2703.         if(j >= l2) {
  2704.              rtnk = k-i;
  2705.             return((char *)&b1[i]);
  2706.         }
  2707.         if(iskanji(b1[i])) i++;
  2708.     }
  2709.     return((char *)NULL);
  2710. }
  2711.  
  2712. void xxfseek(PCELL far *pt, long l)
  2713. {
  2714.     tbl_set(pt);
  2715.     if(cfno != pt->p->fno) {
  2716.         xfclose();
  2717.         if(maxfno > 1) _fstrcpy((char far *)filename,file[pt->p->fno-1]);
  2718.         xfopen(filename);
  2719.         cfno = pt->p->fno;
  2720.     }
  2721.     xfseek(l);
  2722. }
  2723.  
  2724. FILE *xxfopen(char *path,char *mode)
  2725. {
  2726.     FILE *fd1;
  2727.     char a[129],*b,c;
  2728.     struct stat sbuf;
  2729.  
  2730.     xxstrncpy(a,path,128);
  2731.     b = a;
  2732.     if(isalpha(b[0]) && b[1] == ':')
  2733.         b += 2;
  2734.     if(b[0] == '\\')
  2735.         b++;
  2736.     while(1) {
  2737.         for(;*b && *b != '\\'; b++)
  2738.             if(iskanji(b[0]) && iskanji2(b[1]))
  2739.                 b++;
  2740.         if(!*b) goto xfopen1;
  2741.         c = *b;
  2742.         *b = 0;
  2743.         if(!stat(a,&sbuf)) {
  2744.             if(!(sbuf.st_mode & S_IFDIR))
  2745.                 goto xfopen2;
  2746.         }
  2747.         else {
  2748.             if(mkdir(a))
  2749.                 goto xfopen2;
  2750.         }
  2751.         *b++ = c;
  2752.     }
  2753. xfopen1: 
  2754.     if(!(fd1 = fopen(path,mode))) {
  2755. xfopen2:
  2756.         sprintf(a,"%sファイルのオープンに失敗",path);
  2757.         errdisp2(a);
  2758.         return((FILE *)0);
  2759.     }
  2760.     return(fd1);
  2761. }
  2762.  
  2763. #define MAXBUF 8192
  2764. static int fh;
  2765. static long fdsize=0;
  2766. static long fpoint=0;
  2767. static long toppoint=0;
  2768. static long tailpoint=0;
  2769. static long cpoint=0;
  2770. static char fbuffer[MAXBUF];
  2771. FILE *xfopen(char *filename) {
  2772.  
  2773.     if(fd = fopen(filename,"rb")) {
  2774.         fh = fileno(fd);
  2775.         fdsize = filelength(fh);
  2776.         if(!fseek(fd,-1,SEEK_END))
  2777.             if(fgetc(fd) == 0x1a) fdsize--;
  2778.         fseek(fd,0,SEEK_SET);
  2779.         fpoint = 0;
  2780.         tailpoint = 0;
  2781.     }
  2782.     return(fd);
  2783. }
  2784.  
  2785. int xfclose(void) {
  2786.     return(fclose(fd));
  2787. }
  2788.  
  2789. int xfseek(long offset) {
  2790.     long x;
  2791.  
  2792.     x = fpoint;
  2793.     fpoint = offset;
  2794.     cpoint = fpoint % MAXBUF;
  2795.     return((int)x);
  2796. }
  2797.  
  2798. long xftell(void) {
  2799.     return(fpoint);
  2800. }
  2801.  
  2802. int xfgetc(void) {
  2803.     if(fpoint < toppoint || fpoint >= tailpoint || !tailpoint) {
  2804.         toppoint = fpoint / MAXBUF;
  2805.         cpoint = fpoint % MAXBUF;
  2806.         toppoint *= MAXBUF;
  2807.         lseek(fh,toppoint,0);
  2808.         tailpoint = read(fh,fbuffer,MAXBUF);
  2809.         if(tailpoint <= 0) fpoint = fdsize;
  2810.         else tailpoint += toppoint;
  2811.     }
  2812.     fpoint++;
  2813.     return((int)fbuffer[cpoint++]);
  2814. }
  2815.  
  2816. int xfeof(void) {
  2817.     if(fdsize <= fpoint) return(1);
  2818.     return(0);
  2819. }
  2820.  
  2821. char *xfgets(char *s, int n) {
  2822.     char *a;
  2823.     int c;
  2824.  
  2825.     if(fdsize <= fpoint) return((char *)0);
  2826.     a = s;
  2827.     for(; n-1;) {
  2828.         if(fpoint < toppoint || fpoint >= tailpoint || !tailpoint) {
  2829.             toppoint = fpoint / MAXBUF;
  2830.             cpoint = fpoint % MAXBUF;
  2831.             toppoint *= MAXBUF;
  2832.             lseek(fh,toppoint,0);
  2833.             tailpoint = read(fh,fbuffer,MAXBUF);
  2834.             if(tailpoint <= 0) fpoint = fdsize;
  2835.             else tailpoint += toppoint;
  2836.         }
  2837.         if(fdsize <= fpoint) {
  2838.             if(a == s) return((char *)0);
  2839.             break;
  2840.         }
  2841.         c = (int)fbuffer[cpoint++];
  2842.         fpoint++;
  2843.         if(c == 0x00) {
  2844.             foutmode |= F_UPDATE;
  2845.             continue;
  2846.         }
  2847.         if(c == 0x1a) {
  2848.             if(fdsize > fpoint)
  2849.                 foutmode |= F_UPDATE;
  2850.             continue;
  2851.         }
  2852.         if(c == 0x0d) continue;
  2853.         *a++ = (char)c;
  2854.         n--;
  2855.         if(c == 0x0a)
  2856.             break;
  2857.     }
  2858.     *a = 0;
  2859.     return(s);
  2860. }
  2861.  
  2862. void xxstrncpy(char *s,char *d,int c)
  2863. {
  2864.     memset(s,0,c+1);
  2865.     strncpy(s,d,c);
  2866. }
  2867.  
  2868. void xxstrncpy80(char *s,char *d)
  2869. {
  2870.     xxstrncpy(s,d,80);
  2871. }
  2872.  
  2873. void xxstrncpy50(char *s,char *d)
  2874. {
  2875.     xxstrncpy(s,d,50);
  2876. }
  2877.  
  2878. int xstrncmp(char *s,char *d)
  2879. {
  2880. /*    return(strncmp(s,d,strlen(d))); */
  2881.     while(*s == *d) {
  2882.         if(!*d) return(0);
  2883.         s++;
  2884.         d++;
  2885.         if(!*d) return(0);
  2886.     }
  2887.     return(1);
  2888. }
  2889.  
  2890. int xstrcmp(char *s,char *d)
  2891. {
  2892.     while(*s == *d) {
  2893.         if(!*d) return(0);
  2894.         s++;
  2895.         d++;
  2896.     }
  2897.     return(1);
  2898. }
  2899.  
  2900. void strncat80(char *msg,char *buf)
  2901. {
  2902.     strncat(msg,buf,80-strlen(msg));
  2903. }
  2904.  
  2905. #ifdef FMR
  2906. static char *pfkeytbl[265] = {
  2907.     "^@",    "^A",    "^B",    "^C",    "^D",    "^E",    "^F",     "^G",
  2908.     "BS",    "TAB",   "^J",    "^K",    "^L",    "リターン",  "^N",     "^O",
  2909.     "^P",    "^Q",    "^R",    "^S",    "^T",    "^U",    "^V",     "^W",
  2910.     "^X",    "^Y",    "^Z",    "ESC",   "^\\",   "^]",    "^^",     "^_",
  2911.     "空白",  "!",     """",    "#",     "$",     "%",     "&",      "'",
  2912.     "(",     ")",     "*",     "+",     ",",     "-",     ".",      "/",
  2913.     "0",     "1",     "2",     "3",     "4",     "5",     "6",      "7",
  2914.     "8",     "9",     ":",     ";",     "<",     "=",     ">",      "?",
  2915.     "@",     "A",     "B",     "C",     "D",     "E",     "F",      "G",
  2916.     "H",     "I",     "J",     "K",     "L",     "M",     "N",      "O",
  2917.     "P",     "Q",     "R",     "S",     "T",     "U",     "V",      "W",
  2918.     "X",     "Y",     "Z",     "[",     "\\",    "]",     "^",      "~",
  2919.     "`",     "a",     "b",     "c",     "d",     "e",     "f",      "g",
  2920.     "h",     "i",     "j",     "k",     "l",     "m",     "n",      "o",
  2921.     "p",     "q",     "r",     "s",     "t",     "u",     "v",      "w",
  2922.     "x",     "y",     "z",     "{",     "|",     "}",     "0x7E",   "",
  2923.     "",      "PF1",   "PF2",   "PF3",   "PF4",   "PF5",   "PF6",    "PF7",
  2924.     "PF8",   "PF9",   "PF10",  "PF11",  "PF12",  "PF13",  "PF14",   "PF15",
  2925.     "↑",    "↓",    "←",    "→",    "前行",  "次行",  "HOME",   "センタリング",
  2926.     "挿入",  "削除",  "実行",  "取消",  "前頁",  "頁指定","次頁",   "改頁",
  2927.     "S+リターン","S+PF1", "S+PF2", "S+PF3", "S+PF4", "S+PF5", "S+PF6",  "S+PF7",
  2928.     "S+PF8", "S+PF9", "S+PF10","S+PF11","S+PF12","S+PF13","S+PF14", "S+PF15",
  2929.     "S+↑",  "S+↓",  "S+←",  "S+→",  "S+前行","S+次行","CLS",   "S+センタリング",
  2930.     "S+挿入","S+削除","S+実行","S+取消","S+前頁","S+頁指定","S+次頁","S+改頁",
  2931.     "C+リターン","C+PF1", "C+PF2", "C+PF3", "C+PF4", "C+PF5", "C+PF6",  "C+PF7",
  2932.     "C+PF8", "C+PF9", "C+PF10","C+PF11","C+PF12","C+PF13","C+PF14", "C+PF15",
  2933.     "C+↑",  "C+↓",  "C+←",  "C+→",  "C+前行","C+次行","C+HOME","C+センタリング",
  2934.     "C+挿入","C+削除","C+実行","C+取消","C+前頁","C+頁指定","C+次頁","C+改頁",
  2935.     "PF16",  "PF17",  "PF18",  "PF19",  "PF20",  "",      "",       "",
  2936.     "S+PF16","S+PF17","S+PF18","S+PF19","S+PF20","",      "",       "",
  2937.     "C+PF16","C+PF17","C+PF18","C+PF19","C+PF20","SC+PF1","SC+PF2", "SC+PF3",
  2938.     "SC+PF4","SC+PF5","SC+PF6","SC+PF7","SC+PF8","SC+PF9","SC+PF10",""
  2939. };
  2940. #endif
  2941. #ifdef PC_98
  2942. static char *pfkeytbl[265] = {
  2943.     "^@",    "^A",    "^B",    "^C",    "^D",    "^E",    "^F",     "^G",
  2944.     "BS",    "TAB",   "^J",    "^K",    "^L",    "リターン",  "^N",     "^O",
  2945.     "^P",    "^Q",    "^R",    "^S",    "^T",    "^U",    "^V",     "^W",
  2946.     "^X",    "^Y",    "^Z",    "ESC",   "^\\",   "^]",    "^^",     "^_",
  2947.     "空白",  "!",     """",    "#",     "$",     "%",     "&",      "'",
  2948.     "(",     ")",     "*",     "+",     ",",     "-",     ".",      "/",
  2949.     "0",     "1",     "2",     "3",     "4",     "5",     "6",      "7",
  2950.     "8",     "9",     ":",     ";",     "<",     "=",     ">",      "?",
  2951.     "@",     "A",     "B",     "C",     "D",     "E",     "F",      "G",
  2952.     "H",     "I",     "J",     "K",     "L",     "M",     "N",      "O",
  2953.     "P",     "Q",     "R",     "S",     "T",     "U",     "V",      "W",
  2954.     "X",     "Y",     "Z",     "[",     "\\",    "]",     "^",      "~",
  2955.     "`",     "a",     "b",     "c",     "d",     "e",     "f",      "g",
  2956.     "h",     "i",     "j",     "k",     "l",     "m",     "n",      "o",
  2957.     "p",     "q",     "r",     "s",     "t",     "u",     "v",      "w",
  2958.     "x",     "y",     "z",     "{",     "|",     "}",     "0x7E",   "",
  2959.     "",      "f・1",   "f・2",   "f・3",   "f・4",   "f・5",   "f・6",    "f・7",
  2960.     "f・8",   "f・9",   "f・10",  "vf・1",  "vf・2",  "vf・3",  "vf・4",   "vf・5",
  2961.     "↑",    "↓",    "←",    "→",    "ROLLUP","ROLLDOWN","HOME", "HELP",
  2962.     "INS",   "DEL",   "",      "",      "",      "",      "",       "",
  2963.     "S+リターン","S+f・1", "S+f・2", "S+f・3", "S+f・4", "S+f・5", "S+f・6",  "S+f・7",
  2964.     "S+f・8", "S+f・9", "S+f・10","S+vf・1","S+vf・2","S+vf・3","S+vf・4", "S+vf・5",
  2965.     "S+↑",  "S+↓",  "S+←",  "S+→",  "S+ROLLUP","S+ROLLDOWN","CLS","S+HELP",
  2966.     "S+INS", "S+DEL", "",      "",      "",      "",      "",       "",
  2967.     "C+リターン","C+f・1", "C+f・2", "C+f・3", "C+f・4", "C+f・5", "C+f・6",  "C+f・7",
  2968.     "C+f・8", "C+f・9", "C+f・10","C+vf・1","C+vf・2","C+vf・3","C+vf・4", "C+vf・5",
  2969.     "C+↑",  "C+↓",  "C+←","C+→","C+ROOLUP","C+ROLLDOWN","C+HOME","C+HELP",
  2970.     "C+INS", "C+DEL", "",      "",      "",      "",      "",       "",
  2971.     "",      "",      "",      "",      "",      "",      "",       "",
  2972.     "",      "",      "",      "",      "",      "",      "",       "",
  2973.     "",      "",      "",      "",      "",      "SC+f・1","SC+f・2", "SC+f・3",
  2974.     "SC+f・4","SC+f・5","SC+f・6","SC+f・7","SC+f・8","SC+f・9","SC+f・10",""
  2975. };
  2976. #endif
  2977. #ifdef PC_AT
  2978. static char *pfkeytbl[265] = {
  2979.     "^@",    "^A",    "^B",    "^C",    "^D",    "^E",    "^F",     "^G",
  2980.     "BS",    "TAB",   "^J",    "^K",    "^L",    "リターン",  "^N",     "^O",
  2981.     "^P",    "^Q",    "^R",    "^S",    "^T",    "^U",    "^V",     "^W",
  2982.     "^X",    "^Y",    "^Z",    "ESC",   "^\\",   "^]",    "^^",     "^_",
  2983.     "空白",  "!",     """",    "#",     "$",     "%",     "&",      "'",
  2984.     "(",     ")",     "*",     "+",     ",",     "-",     ".",      "/",
  2985.     "0",     "1",     "2",     "3",     "4",     "5",     "6",      "7",
  2986.     "8",     "9",     ":",     ";",     "<",     "=",     ">",      "?",
  2987.     "@",     "A",     "B",     "C",     "D",     "E",     "F",      "G",
  2988.     "H",     "I",     "J",     "K",     "L",     "M",     "N",      "O",
  2989.     "P",     "Q",     "R",     "S",     "T",     "U",     "V",      "W",
  2990.     "X",     "Y",     "Z",     "[",     "\\",    "]",     "^",      "~",
  2991.     "`",     "a",     "b",     "c",     "d",     "e",     "f",      "g",
  2992.     "h",     "i",     "j",     "k",     "l",     "m",     "n",      "o",
  2993.     "p",     "q",     "r",     "s",     "t",     "u",     "v",      "w",
  2994.     "x",     "y",     "z",     "{",     "|",     "}",     "0x7E",   "",
  2995.     "",      "F1",    "F2",    "F3",    "F4",    "F5",    "F6",     "F7",
  2996.     "F8",    "F9",    "F10",   "F11",   "F12",   "F13",   "F14",    "F15",
  2997.     "↑",    "↓",    "←",    "→",    "PgUp",  "PgDn",  "Home",   "",
  2998.     "Ins",   "Del",   "End",   "",      "",      "",      "",       "",
  2999.     "S+リターン","S+F1",  "S+F2",  "S+F3",  "S+F4",  "S+F5",  "S+F6",   "S+F7",
  3000.     "S+F8",  "S+F9",  "S+F10", "S+F11", "S+F12", "S+F13", "S+F14",  "S+F15",
  3001.     "S+↑",  "S+↓",  "S+←",  "S+→",  "S+PgUp","S+PgDn","S+Home", "",
  3002.     "S+Ins", "S+Del", "S+End", "",      "",      "",      "",       "",
  3003.     "C+リターン","C+F1",  "C+F2",  "C+F3",  "C+F4",  "C+F5",  "C+F6",   "C+F7",
  3004.     "C+F8",  "C+F9",  "C+F10", "C+F11", "C+F12", "C+F13", "C+F14",  "C+F15",
  3005.     "C+↑",  "C+↓",  "C+←",  "C+→",  "C+PgUp","C+PgDn","C+Home", "",
  3006.     "C+Ins", "C+Del", "C+End", "",      "",      "",      "",       "",
  3007.     "F16",   "F17",   "F18",   "F19",   "F20",   "",      "",       "",
  3008.     "S+F16", "S+F17", "S+F18", "S+F19", "S+F20", "",      "",       "",
  3009.     "C+F16", "C+F17", "C+F18", "C+F19", "C+F20", "A+F1",  "A+F2",  "A+F3",
  3010.     "A+F4",  "A+F5",  "A+F6",  "A+F7",  "A+F8",  "A+F9",  "A+F10",""
  3011. };
  3012. #endif
  3013.  
  3014. struct helptbl {
  3015.     char code;
  3016.     char *string;
  3017. };
  3018.  
  3019. #ifndef PC_AT
  3020. #define HELP1NO 42
  3021. #else
  3022. #define HELP1NO 41
  3023. #endif
  3024. static struct helptbl help1tbl[HELP1NO] = {
  3025.     0x90," ↑      …行スクロール(前行)",
  3026.     0x91," ↓      …行スクロール(次行)",
  3027.     0x92," ←      …頁スクロール(前画面)",
  3028.     0x93," →      …頁スクロール(次画面)",
  3029.     0xff," 選択    …内容の選択と取消し",
  3030.     0x0d," リターン…タイトル一覧表示に戻る",
  3031.     0x1b," ESC     …タイトル一覧表示に戻る",
  3032.     0x81,"[ 終了]…タイトル一覧表示に戻る",
  3033.     0x82,"[ トップ]…先頭頁に移動",
  3034.     0x83,"[ ラスト ]…最終頁に移動",
  3035.     0x84,"[ヘルプ ] …ヘルプ呼び出し",
  3036.     0x85,"[ 切出]…選択内容のファイル出力と削除指定",
  3037.     0x86,"[ 削除]…選択内容の削除指定",
  3038.     0x87,"[ コピー]…選択内容のファイル出力",
  3039.     0x88,"[ 検索]…指定単語での検索して個数通知",
  3040.     0x89,"[ ID]…IDによる絞り込み",
  3041.     0x8a,"[ コメント]…会議室等のコメントツリー絞り込み",
  3042.     0x8a,"[ ノーマル]…検索/コメント/ID/コメント+IDからノーマルへ",
  3043.     0xa1,"[ DOS ]…MS-DOSコマンドの呼び出し",
  3044.     0xa2,"[ 前項]…前の内容に移動",
  3045.     0xa3,"[ 次項]…次の内容に移動",
  3046.     0xa5,"[ 取消]…選択した全てを取消し",
  3047.     0xa6,"[削キャン]…削除指定を取消し",
  3048.     0xa7,"[タグ設]…タグ設定内容にする",
  3049.     0xa8,"[タグ←]…前のタグ設定内容に移動",
  3050.     0xa9,"[タグ→]…次のタグ設定内容に移動",
  3051.     0xaa,"[ 発言]…内容をファイル出力してエディタ起動(1)",
  3052.     0xc2,"[ タイトル]…タイトル一覧をファイル出力",
  3053.     0xc3,"[<検索]…前タイトルと内容を検索して移動",
  3054.     0xc4,"[検索>]…後タイトルと内容を検索して移動",
  3055.     0xc5,"[ 印刷]…選択内容をファイル出力して印刷依頼",
  3056. #ifndef PC_AT
  3057.     0xc8,"[20/25]…画面の20/25行切換",
  3058. #endif
  3059.     0xc9,"[ ユーザ]…利用者コマンドの実行",
  3060.     0xca,"[オート表]…自動表示",
  3061.     0xf6,"[ +10 ]…10タイトル先の内容に移動",
  3062.     0xf7,"[ +20 ]…20タイトル先の内容に移動",
  3063.     0xf8,"[ +50 ]…50タイトル先の内容に移動",
  3064.     0xf9,"[既セット]…この内容までを既読状態に設定",
  3065.     0xfa,"[既キャン]…この内容以降を既読状態取消し",
  3066.     0xfb,"[JUMP@]…ジャンプモードの切替",
  3067.     0xfd,"[コメ+ID]…コメントツリーとタイトルのIDで絞り込み",
  3068.     0xfe,"[発言2]…内容をファイル出力してエディタ起動(2)"
  3069. };
  3070.  
  3071. #ifndef PC_AT
  3072. #define HELP2NO 48
  3073. #else
  3074. #define HELP2NO 47
  3075. #endif
  3076. static struct helptbl help2tbl[HELP2NO] = {
  3077.     0x90," ↑      …行スクロール(前行)",
  3078.     0x91," ↓      …行スクロール(次行)",
  3079.     0x92," ←      …頁スクロール(前画面)",
  3080.     0x93," →      …頁スクロール(次画面)",
  3081.     0xff," 選択    …タイトル内容の選択と取消し",
  3082.     0x0d," リターン…内容を表示",
  3083.     0x1b," ESC     …ノーマルモードへの復帰,NIFPを終了",
  3084.     0x81,"[ 終了]…NIFPを終了",
  3085.     0x82,"[ トップ]…先頭タイトルに移動",
  3086.     0x83,"[ ラスト ]…最終タイトルに移動",
  3087.     0x84,"[ヘルプ ] …ヘルプ呼び出し",
  3088.     0x85,"[ 切出]…選択内容のファイル出力と削除指定",
  3089.     0x86,"[ 削除]…選択内容の削除指定",
  3090.     0x87,"[ コピー]…選択内容のファイル出力",
  3091.     0x88,"[ 検索]…指定単語での検索絞り込み",
  3092.     0x89,"[ ID]…IDによる絞り込み",
  3093.     0x8a,"[ コメント]…会議室等のコメントツリー絞り込み",
  3094.     0x8a,"[ ノーマル]…検索/コメント/ID/コメント+IDからノーマルへ",
  3095.     0xa1,"[ DOS ]…MS-DOSコマンドの呼び出し",
  3096.     0xa2,"[<ファイル]…前のログファイルに移動",
  3097.     0xa3,"[ファイル>]…次のログファイルに移動",
  3098.     0xa4,"[ファイル#]…指定のログファイルに移動",
  3099.     0xa5,"[ 取消]…選択した全てを取消し",
  3100.     0xa6,"[削キャン]…削除指定を取消し",
  3101.     0xa7,"[タグ設]…タグ設定タイトルにする",
  3102.     0xa8,"[タグ←]…前のタグ設定タイトルに移動",
  3103.     0xa9,"[タグ→]…次のタグ設定タイトルに移動",
  3104.     0xaa,"[ 発言]…内容をファイル出力してエディタ起動(1)",
  3105.     0xc1,"[ 書終]…強制的にログファイルを書き込み終了",
  3106.     0xc2,"[ タイトル]…タイトル一覧をファイル出力",
  3107.     0xc3,"[<検索]…前のタイトルを検索して移動",
  3108.     0xc4,"[検索>]…後のタイトルを検索して移動",
  3109.     0xc5,"[ 印刷]…選択内容をファイル出力して印刷依頼",
  3110.     0xc6,"[ログ大]…ログ整理(大分類)",
  3111.     0xc7,"[ログ詳]…ログ整理(詳細分類)",
  3112. #ifndef PC_AT
  3113.     0xc8,"[20/25]…画面の20/25行切換",
  3114. #endif
  3115.     0xc9,"[ ユーザ]…利用者コマンドの実行",
  3116.     0xca,"[オート表]…自動表示",
  3117.     0xf5,"[キャン終]…未読情報を出力せずに終了",
  3118.     0xf6,"[ +10 ]…10タイトル先のタイトルに移動",
  3119.     0xf7,"[ +20 ]…20タイトル先のタイトルに移動",
  3120.     0xf8,"[ +50 ]…50タイトル先のタイトルに移動",
  3121.     0xf9,"[既セット]…このタイトルまでを既読状態に設定",
  3122.     0xfa,"[既キャン]…このタイトル以降を既読状態取消し",
  3123.     0xfb,"[JUMP@]…ジャンプモードの切替",
  3124.     0xfc,"[ TYPE]…内容(ESCシーケンス付も可)をTYPE表示",
  3125.     0xfd,"[コメ+ID]…コメントツリーとタイトルのIDで絞り込み",
  3126.     0xfe,"[発言2]…内容をファイル出力してエディタ起動(2)"
  3127. };
  3128.  
  3129. void help(int mode)            /* ヘルプ */
  3130. {
  3131.     int l,savel,i,j,k,m,no;
  3132.     struct helptbl *helptbl;
  3133.     char buf[50],a,c,msg1[50],*msg2;
  3134.  
  3135.     allclr();
  3136.     savel = line;
  3137.     setline(0);
  3138.     l = line = getline();
  3139.     l -= 10;
  3140.     topdisp();
  3141.     pfdisp(0);
  3142.     i = 1;
  3143.     for(;;) {
  3144.         if(mode) {
  3145.             helptbl = help1tbl;
  3146.             no = HELP1NO;
  3147.             strcpy(msg1," 内容表示画面のキー操作説明");
  3148.         }
  3149.         else {
  3150.             helptbl = help2tbl;
  3151.             no = HELP2NO;
  3152.             strcpy(msg1," タイトル一覧表示画面のキー操作説明");
  3153.         }
  3154.         if(i == 1) {
  3155.             msg2 = "ESC・リターンキー:戻る  SPACEキー:次頁";
  3156.             m = 1;
  3157.         }
  3158.         else if(i+l < no) {
  3159.             msg2 = "ESC・リターンキー:戻る  TABキー:前頁  SPACEキー:次頁";
  3160.             m = 2;
  3161.         }
  3162.         else {
  3163.             msg2 = "ESC・リターンキー:戻る  TABキー:前頁";
  3164.             m = 3;
  3165.         }
  3166.         j = (i+l-1)/l;
  3167.         k = (no+l-1)/l;
  3168.         sprintf(buf," (%d/%d)",j,k);
  3169.         strcat(msg1,buf);
  3170.         waku_disp(2,3,l+4,76,msg1,msg2);
  3171.         loc(10,5);print("機能の説明");
  3172.         loc(45,5);print("キーの種類");
  3173.         for(j=0;j < l && i+j <= no;) {
  3174.             loc(3,6+j);
  3175.             print(helptbl[i+j-1].string);
  3176.             buf[0] = 0;
  3177.             for(k=0,c=helptbl[i+j-1].code;k < 256;k++) {
  3178.                 if(keytbl[k] != c || !strlen(pfkeytbl[k])) continue;
  3179.                 if(strlen(buf)+strlen(pfkeytbl[k]) > 32) break;
  3180.                 if(strlen(buf)) strcat(buf,",");
  3181.                 strcat(buf,pfkeytbl[k]);
  3182.             }
  3183.             loc(45,6+j);print(buf);
  3184.             j++;
  3185.         }
  3186.         loc(6,l+7);print("JUMP@ 「 」:前後の内容へ  「-」:MAIL/HP/MESの内容へ 「*」:未読の内容へ");
  3187.          locate(1,1);
  3188.         regs.x.ax = 0x0cff;
  3189.         xintdos();
  3190.         for(;a = getch();) {
  3191.             if(a == 0xff) {
  3192.                 getch();
  3193.                 continue;
  3194.             }
  3195.             if(a == 0x1b || a == '\r') {
  3196.                 j = 0;
  3197.                 break;
  3198.             }
  3199.             if(a == 0x09) {        /* TABキー */
  3200.                 if(m == 1) continue;
  3201.                 j = 2;
  3202.                 break;
  3203.             }
  3204.             if(a == ' ') {        /* SPACEキー */
  3205.                 if(m == 3) continue;
  3206.                 j = 1;
  3207.                 break;
  3208.             }
  3209.         }
  3210.         if(j == 0) break;
  3211.         if(j == 1) i += l;
  3212.         if(j == 2) i -= l;
  3213.     }
  3214.     allclr();
  3215.     line = savel;
  3216.     setline(line);
  3217. }
  3218.  
  3219. PCELL far *tbl_alloc(int mode)    /* タイトルテーブル獲得 & 初期化 */
  3220. {
  3221.     PCELL3 far *pt;
  3222.     PCELL2 far *pt1;
  3223.     PCELL far *pt2;
  3224.     PCELL far *pt3;
  3225.     int i;
  3226.  
  3227.     if(!p_freetop) {
  3228.         pt = (PCELL3 far *)farmalloc(sizeof(PCELL3));
  3229.         if(!pt) {
  3230.             return((PCELL far *)0);
  3231.         }
  3232.         if(emsno) {
  3233.             if(emsno != 999 && ems_count >= emsno) {
  3234.                 farfree(pt);
  3235.                 return((PCELL far *)0);
  3236.             }
  3237.             if(ems_add(ems_count+1)) {
  3238.                 farfree(pt);
  3239.                 return((PCELL far *)0);
  3240.             }
  3241.             ems_set(ems_count);
  3242.             ems_lno = ems_count;
  3243.             ems_count++;
  3244.             ems_seg = ems_getseg();
  3245.             pt1 = (PCELL2 far *)MK_FP(ems_seg,0);
  3246.         }
  3247.         else {
  3248.             pt1 = farmalloc(sizeof(PCELL2) * MAXTBL);
  3249.             if(!pt1) {
  3250.                 farfree(pt);
  3251.                 return((PCELL far *)0);
  3252.             }
  3253.         }
  3254.         _fmemset((char far *)pt,0,sizeof(PCELL3));
  3255.         _fmemset((char far *)pt1,0,sizeof(PCELL2) * MAXTBL);
  3256.         for(p_freetop = pt2 = (PCELL far *)pt->tbl,i=0;i < MAXTBL;) {
  3257.             if(emsno) pt2->lno = ems_lno;
  3258.             else      pt2->lno = i;
  3259.             pt2->p = pt1;
  3260.             pt1++;
  3261.             if(++i >= MAXTBL) break;
  3262.             pt3 = (PCELL far *)(pt2+1);
  3263.             pt2->next = pt3;
  3264.             pt2 = pt3;
  3265.         }
  3266.         pt2->next = (PCELL far *)0;
  3267. /*        if(p_tbltop) {
  3268.             p_tbltop->next = pt;
  3269.         }
  3270.         else {
  3271.             p_tbltop = pt;
  3272.         }
  3273.         pt->next = (PCELL3 far *)0; */
  3274.         pt->next = p_tbltop;
  3275.         p_tbltop = pt;
  3276.     }
  3277.     if(!mode) {
  3278.         pt2 = p_freetop;
  3279.         p_freetop = pt2->next;
  3280.         pt2->next = pt2->back = pt2->grp = (PCELL far *)0;
  3281.         pt2->mode = pt2->flag = 0;
  3282.         pt2->count = 0;
  3283.         pt1 = pt2->p;
  3284.         tbl_set(pt2);
  3285.         _fmemset((char far *)pt1,0,sizeof(PCELL2));
  3286.         return(pt2);
  3287.     }
  3288.     return(p_freetop);
  3289. }
  3290.  
  3291. void tbl_free(PCELL far *pt)    /* タイトルテーブル返却 */
  3292. {
  3293.     if(pt) {
  3294.         pt->next = p_freetop;
  3295.         p_freetop = pt;
  3296.     }
  3297. }
  3298.  
  3299. void tbl_set(PCELL far *pt)        /* EMSメモリ空間セット */
  3300. {
  3301.     if(emsno && ems_lno != pt->lno) {
  3302.         ems_set(pt->lno);
  3303.         ems_lno = pt->lno;
  3304.     }
  3305. }
  3306. static int ems_func(char i)        /* EMS機能呼び出しサブ */
  3307. {
  3308.     regs.h.ah = i;
  3309.     int86x(0x67,®s,®s,&sregs);
  3310.     i = regs.h.ah;
  3311.     return((int)i);
  3312. }
  3313.  
  3314. static char emsname[9] = "NIFP0   ";
  3315. int ems_add(int no)                /* EMS1ページ獲得 */
  3316. {
  3317.     int i;
  3318.  
  3319.     if(no == 1) {
  3320.         regs.x.bx = 1;
  3321.         if(ems_func(0x43)) return(-1);
  3322.         ems_handle = regs.x.dx;
  3323.         for(i=0;i<10;i++) {
  3324.             sprintf(&emsname[4],"%d",i);
  3325.             regs.h.al = 1;
  3326.             regs.x.si = (unsigned)emsname;
  3327.             if(ems_func(0x54)) break;
  3328.         }
  3329.         regs.h.al = 1;
  3330.         regs.x.dx = ems_handle;
  3331.         regs.x.si = (unsigned)emsname;
  3332.         if(ems_func(0x53)) {
  3333.             ems_free();
  3334.             return(-1);
  3335.         }
  3336.     }
  3337.     else {
  3338.         regs.x.bx = no;
  3339.         regs.x.dx = ems_handle;
  3340.         if(ems_func(0x51)) return(-1);
  3341.     }
  3342.     return(0);
  3343. }
  3344.  
  3345. int ems_set(int no)                /* EMSを物理アドレスにマップ */
  3346. {
  3347.     regs.x.bx = no;
  3348.     regs.h.al = 0;
  3349.     regs.x.dx = ems_handle;
  3350.     if(ems_func(0x44)) return(-1);
  3351.     return(0);
  3352. }
  3353.  
  3354. int ems_check(void)                /* EMSが存在するかチェック */
  3355. {
  3356.     char far *add;
  3357.  
  3358.     regs.h.ah = 0x35;
  3359.     regs.h.al = 0x67;
  3360.     intdosx(®s,®s,&sregs);
  3361.     add = (char far *)MK_FP(sregs.es,0x000a);
  3362.     if(*add++ != 'E' || *add++ != 'M' || *add != 'M') {
  3363.         return(0);
  3364.     }
  3365.     return(1);
  3366. }
  3367.  
  3368. long ems_getseg(void)            /* EMS物理セグメントアドレス読み込み */
  3369. {
  3370.     ems_func(0x41);
  3371.     return((long)regs.x.bx);
  3372. }
  3373.  
  3374. int ems_free(void)                /* EMS返却 */
  3375. {
  3376.     if(ems_count) {
  3377.         regs.x.dx = ems_handle;
  3378.         if(ems_func(0x45)) return(-1);
  3379.         ems_count = 0;
  3380.     }
  3381.     return(0);
  3382. }
  3383.  
  3384. /*
  3385. char far *_fstrcpy(char far *d,char far *s) {
  3386.     for(;;) {
  3387.         *d++ = *s;
  3388.         if(!*s++) break;
  3389.     }
  3390.     return(d);
  3391. }
  3392.  
  3393. char far *_fstrncpy(char far *d,char far *s,int n) {
  3394.     for(;n;n--) {
  3395.         *d++ = *s;
  3396.         if(!*s++) break;
  3397.     }
  3398.     return(d);
  3399. }
  3400.  
  3401. int _fstrcmp(char far *s1,char far *s2) {
  3402.     for(;*s1 && *s2;) {
  3403.         if(*s1 < *s2) return(-1);
  3404.         if(*s1 > *s2) return(1);
  3405.         s1++;
  3406.         s2++;
  3407.     }
  3408.     return(0);
  3409. }
  3410.  
  3411. char far *_fmemset(char far *s,char c,int n) {
  3412.     for(;n;n--)
  3413.         *s++ = c;
  3414.     return(s);
  3415. }
  3416.  
  3417. char far *_fmemcpy(char far *d,char far *s,int n) {
  3418.     for(;n;n--)
  3419.         *d++ = *s++;
  3420.     return(d);
  3421. }
  3422.  
  3423. int _fmemcmp(char far *s1,char far *s2,int n) {
  3424.     for(;n;n--) {
  3425.         if(*s1 < *s2) return(-1);
  3426.         if(*s1 > *s2) return(1);
  3427.         s1++;
  3428.         s2++;
  3429.     }
  3430.     return(0);
  3431. }
  3432. */
  3433.